home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tcl8.0 / generic / tclBasic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  119.0 KB  |  3,993 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tclBasic.c --
  3.  *
  4.  *    Contains the basic facilities for TCL command interpretation,
  5.  *    including interpreter creation and deletion, command creation
  6.  *    and deletion, and command parsing and execution.
  7.  *
  8.  * Copyright (c) 1987-1994 The Regents of the University of California.
  9.  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
  10.  *
  11.  * See the file "license.terms" for information on usage and redistribution
  12.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  13.  *
  14.  * SCCS: @(#) tclBasic.c 1.305 97/08/13 10:34:43
  15.  */
  16.  
  17. #include "tclInt.h"
  18. #include "tclCompile.h"
  19. #ifndef TCL_GENERIC_ONLY
  20. #   include "tclPort.h"
  21. #endif
  22.  
  23. /*
  24.  * Static procedures in this file:
  25.  */
  26.  
  27. static void        DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));
  28. static void        HiddenCmdsDeleteProc _ANSI_ARGS_((
  29.                 ClientData clientData, Tcl_Interp *interp));
  30.  
  31. /*
  32.  * The following structure defines the commands in the Tcl core.
  33.  */
  34.  
  35. typedef struct {
  36.     char *name;            /* Name of object-based command. */
  37.     Tcl_CmdProc *proc;        /* String-based procedure for command. */
  38.     Tcl_ObjCmdProc *objProc;    /* Object-based procedure for command. */
  39.     CompileProc *compileProc;    /* Procedure called to compile command. */
  40.     int isSafe;            /* If non-zero, command will be present
  41.                                  * in safe interpreter. Otherwise it will
  42.                                  * be hidden. */
  43. } CmdInfo;
  44.  
  45. /*
  46.  * The built-in commands, and the procedures that implement them:
  47.  */
  48.  
  49. static CmdInfo builtInCmds[] = {
  50.     /*
  51.      * Commands in the generic core. Note that at least one of the proc or
  52.      * objProc members should be non-NULL. This avoids infinitely recursive
  53.      * calls between TclInvokeObjectCommand and TclInvokeStringCommand if a
  54.      * command name is computed at runtime and results in the name of a
  55.      * compiled command.
  56.      */
  57.  
  58.     {"append",        (Tcl_CmdProc *) NULL,    Tcl_AppendObjCmd,
  59.         (CompileProc *) NULL,        1},
  60.     {"array",        (Tcl_CmdProc *) NULL,    Tcl_ArrayObjCmd,
  61.         (CompileProc *) NULL,        1},
  62.     {"binary",        (Tcl_CmdProc *) NULL,    Tcl_BinaryObjCmd,
  63.         (CompileProc *) NULL,        1},
  64.     {"break",        Tcl_BreakCmd,        (Tcl_ObjCmdProc *) NULL,
  65.         TclCompileBreakCmd,        1},
  66.     {"case",        (Tcl_CmdProc *) NULL,    Tcl_CaseObjCmd,
  67.         (CompileProc *) NULL,        1},
  68.     {"catch",        (Tcl_CmdProc *) NULL,    Tcl_CatchObjCmd,    
  69.         TclCompileCatchCmd,        1},
  70.     {"clock",        (Tcl_CmdProc *) NULL,    Tcl_ClockObjCmd,
  71.         (CompileProc *) NULL,        1},
  72.     {"concat",        (Tcl_CmdProc *) NULL,    Tcl_ConcatObjCmd,
  73.         (CompileProc *) NULL,        1},
  74.     {"continue",    Tcl_ContinueCmd,    (Tcl_ObjCmdProc *) NULL,
  75.         TclCompileContinueCmd,        1},
  76.     {"error",        (Tcl_CmdProc *) NULL,    Tcl_ErrorObjCmd,
  77.         (CompileProc *) NULL,        1},
  78.     {"eval",        (Tcl_CmdProc *) NULL,    Tcl_EvalObjCmd,
  79.         (CompileProc *) NULL,        1},
  80.     {"exit",        (Tcl_CmdProc *) NULL,    Tcl_ExitObjCmd,
  81.         (CompileProc *) NULL,        0},
  82.     {"expr",        (Tcl_CmdProc *) NULL,    Tcl_ExprObjCmd,
  83.         TclCompileExprCmd,        1},
  84.     {"fcopy",        (Tcl_CmdProc *) NULL,    Tcl_FcopyObjCmd,
  85.         (CompileProc *) NULL,        1},
  86.     {"fileevent",    Tcl_FileEventCmd,    (Tcl_ObjCmdProc *) NULL,
  87.         (CompileProc *) NULL,        1},
  88.     {"for",        Tcl_ForCmd,        (Tcl_ObjCmdProc *) NULL,
  89.         TclCompileForCmd,        1},
  90.     {"foreach",        (Tcl_CmdProc *) NULL,    Tcl_ForeachObjCmd,
  91.         TclCompileForeachCmd,        1},
  92.     {"format",        (Tcl_CmdProc *) NULL,    Tcl_FormatObjCmd,
  93.         (CompileProc *) NULL,        1},
  94.     {"global",        (Tcl_CmdProc *) NULL,    Tcl_GlobalObjCmd,
  95.         (CompileProc *) NULL,        1},
  96.     {"if",        Tcl_IfCmd,        (Tcl_ObjCmdProc *) NULL,
  97.         TclCompileIfCmd,        1},
  98.     {"incr",        Tcl_IncrCmd,        (Tcl_ObjCmdProc *) NULL,
  99.         TclCompileIncrCmd,        1},
  100.     {"info",        (Tcl_CmdProc *) NULL,    Tcl_InfoObjCmd,
  101.         (CompileProc *) NULL,        1},
  102.     {"interp",        (Tcl_CmdProc *) NULL,    Tcl_InterpObjCmd,
  103.         (CompileProc *) NULL,        1},
  104.     {"join",        (Tcl_CmdProc *) NULL,    Tcl_JoinObjCmd,
  105.         (CompileProc *) NULL,        1},
  106.     {"lappend",        (Tcl_CmdProc *) NULL,    Tcl_LappendObjCmd,
  107.         (CompileProc *) NULL,        1},
  108.     {"lindex",        (Tcl_CmdProc *) NULL,    Tcl_LindexObjCmd,
  109.         (CompileProc *) NULL,        1},
  110.     {"linsert",        (Tcl_CmdProc *) NULL,    Tcl_LinsertObjCmd,
  111.         (CompileProc *) NULL,        1},
  112.     {"list",        (Tcl_CmdProc *) NULL,    Tcl_ListObjCmd,
  113.         (CompileProc *) NULL,        1},
  114.     {"llength",        (Tcl_CmdProc *) NULL,    Tcl_LlengthObjCmd,
  115.         (CompileProc *) NULL,        1},
  116.     {"load",        Tcl_LoadCmd,        (Tcl_ObjCmdProc *) NULL,
  117.         (CompileProc *) NULL,        0},
  118.     {"lrange",        (Tcl_CmdProc *) NULL,    Tcl_LrangeObjCmd,
  119.         (CompileProc *) NULL,        1},
  120.     {"lreplace",    (Tcl_CmdProc *) NULL,    Tcl_LreplaceObjCmd,
  121.         (CompileProc *) NULL,        1},
  122.     {"lsearch",        (Tcl_CmdProc *) NULL,    Tcl_LsearchObjCmd,
  123.         (CompileProc *) NULL,        1},
  124.     {"lsort",        (Tcl_CmdProc *) NULL,    Tcl_LsortObjCmd,
  125.         (CompileProc *) NULL,        1},
  126.     {"namespace",    (Tcl_CmdProc *) NULL,    Tcl_NamespaceObjCmd,
  127.         (CompileProc *) NULL,        1},
  128.     {"package",        Tcl_PackageCmd,        (Tcl_ObjCmdProc *) NULL,
  129.         (CompileProc *) NULL,        1},
  130.     {"proc",        (Tcl_CmdProc *) NULL,    Tcl_ProcObjCmd,    
  131.         (CompileProc *) NULL,        1},
  132.     {"regexp",        Tcl_RegexpCmd,        (Tcl_ObjCmdProc *) NULL,
  133.         (CompileProc *) NULL,        1},
  134.     {"regsub",        Tcl_RegsubCmd,        (Tcl_ObjCmdProc *) NULL,
  135.         (CompileProc *) NULL,        1},
  136.     {"rename",        (Tcl_CmdProc *) NULL,    Tcl_RenameObjCmd,
  137.         (CompileProc *) NULL,        1},
  138.     {"return",        (Tcl_CmdProc *) NULL,    Tcl_ReturnObjCmd,    
  139.         (CompileProc *) NULL,        1},
  140.     {"scan",        Tcl_ScanCmd,        (Tcl_ObjCmdProc *) NULL,
  141.         (CompileProc *) NULL,        1},
  142.     {"set",        Tcl_SetCmd,        (Tcl_ObjCmdProc *) NULL,    
  143.         TclCompileSetCmd,        1},
  144.     {"split",        (Tcl_CmdProc *) NULL,    Tcl_SplitObjCmd,
  145.         (CompileProc *) NULL,        1},
  146.     {"string",        (Tcl_CmdProc *) NULL,    Tcl_StringObjCmd,
  147.         (CompileProc *) NULL,        1},
  148.     {"subst",        Tcl_SubstCmd,        (Tcl_ObjCmdProc *) NULL,
  149.         (CompileProc *) NULL,        1},
  150.     {"switch",        (Tcl_CmdProc *) NULL,    Tcl_SwitchObjCmd,    
  151.         (CompileProc *) NULL,        1},
  152.     {"trace",        Tcl_TraceCmd,        (Tcl_ObjCmdProc *) NULL,
  153.         (CompileProc *) NULL,        1},
  154.     {"unset",        (Tcl_CmdProc *) NULL,    Tcl_UnsetObjCmd,    
  155.         (CompileProc *) NULL,        1},
  156.     {"uplevel",        (Tcl_CmdProc *) NULL,    Tcl_UplevelObjCmd,    
  157.         (CompileProc *) NULL,        1},
  158.     {"upvar",        (Tcl_CmdProc *) NULL,    Tcl_UpvarObjCmd,    
  159.         (CompileProc *) NULL,        1},
  160.     {"variable",    (Tcl_CmdProc *) NULL,    Tcl_VariableObjCmd,
  161.         (CompileProc *) NULL,        1},
  162.     {"while",        Tcl_WhileCmd,        (Tcl_ObjCmdProc *) NULL,    
  163.         TclCompileWhileCmd,        1},
  164.  
  165.     /*
  166.      * Commands in the UNIX core:
  167.      */
  168.  
  169. #ifndef TCL_GENERIC_ONLY
  170.     {"after",        (Tcl_CmdProc *) NULL,    Tcl_AfterObjCmd,
  171.         (CompileProc *) NULL,        1},
  172.     {"cd",        (Tcl_CmdProc *) NULL,    Tcl_CdObjCmd,
  173.         (CompileProc *) NULL,        0},
  174.     {"close",        (Tcl_CmdProc *) NULL,    Tcl_CloseObjCmd,
  175.         (CompileProc *) NULL,        1},
  176.     {"eof",        (Tcl_CmdProc *) NULL,    Tcl_EofObjCmd,
  177.         (CompileProc *) NULL,        1},
  178.     {"fblocked",    (Tcl_CmdProc *) NULL,    Tcl_FblockedObjCmd,
  179.         (CompileProc *) NULL,        1},
  180.     {"fconfigure",    Tcl_FconfigureCmd,    (Tcl_ObjCmdProc *) NULL,
  181.         (CompileProc *) NULL,        0},
  182.     {"file",        (Tcl_CmdProc *) NULL,    Tcl_FileObjCmd,
  183.         (CompileProc *) NULL,        0},
  184.     {"flush",        (Tcl_CmdProc *) NULL,    Tcl_FlushObjCmd,
  185.         (CompileProc *) NULL,        1},
  186.     {"gets",        (Tcl_CmdProc *) NULL,    Tcl_GetsObjCmd,
  187.         (CompileProc *) NULL,        1},
  188.     {"glob",        Tcl_GlobCmd,        (Tcl_ObjCmdProc *) NULL,
  189.         (CompileProc *) NULL,        0},
  190.     {"open",        Tcl_OpenCmd,        (Tcl_ObjCmdProc *) NULL,
  191.         (CompileProc *) NULL,        0},
  192.     {"pid",        (Tcl_CmdProc *) NULL,    Tcl_PidObjCmd,
  193.         (CompileProc *) NULL,        1},
  194.     {"puts",        (Tcl_CmdProc *) NULL,    Tcl_PutsObjCmd,
  195.         (CompileProc *) NULL,        1},
  196.     {"pwd",        Tcl_PwdCmd,        (Tcl_ObjCmdProc *) NULL,
  197.         (CompileProc *) NULL,        0},
  198.     {"read",        (Tcl_CmdProc *) NULL,    Tcl_ReadObjCmd,
  199.         (CompileProc *) NULL,        1},
  200.     {"seek",        Tcl_SeekCmd,        (Tcl_ObjCmdProc *) NULL,
  201.         (CompileProc *) NULL,        1},
  202.     {"socket",        Tcl_SocketCmd,        (Tcl_ObjCmdProc *) NULL,
  203.         (CompileProc *) NULL,        0},
  204.     {"tell",        Tcl_TellCmd,        (Tcl_ObjCmdProc *) NULL,
  205.         (CompileProc *) NULL,        1},
  206.     {"time",        (Tcl_CmdProc *) NULL,    Tcl_TimeObjCmd,
  207.         (CompileProc *) NULL,        1},
  208.     {"update",        Tcl_UpdateCmd,        (Tcl_ObjCmdProc *) NULL,
  209.         (CompileProc *) NULL,        1},
  210.     {"vwait",        Tcl_VwaitCmd,        (Tcl_ObjCmdProc *) NULL,
  211.         (CompileProc *) NULL,        1},
  212.     
  213. #ifdef MAC_TCL
  214.     {"beep",        (Tcl_CmdProc *) NULL,    Tcl_BeepObjCmd,
  215.         (CompileProc *) NULL,        0},
  216.     {"echo",        Tcl_EchoCmd,        (Tcl_ObjCmdProc *) NULL,
  217.         (CompileProc *) NULL,        0},
  218.     {"ls",        Tcl_LsCmd,        (Tcl_ObjCmdProc *) NULL,
  219.         (CompileProc *) NULL,        0},
  220.     {"resource",    (Tcl_CmdProc *) NULL,    Tcl_ResourceObjCmd,
  221.         (CompileProc *) NULL,        1},
  222.     {"source",        (Tcl_CmdProc *) NULL,    Tcl_MacSourceObjCmd,
  223.         (CompileProc *) NULL,        0},
  224. #else
  225.     {"exec",        Tcl_ExecCmd,        (Tcl_ObjCmdProc *) NULL,
  226.         (CompileProc *) NULL,        0},
  227.     {"source",        (Tcl_CmdProc *) NULL,    Tcl_SourceObjCmd,
  228.         (CompileProc *) NULL,        0},
  229. #endif /* MAC_TCL */
  230.     
  231. #endif /* TCL_GENERIC_ONLY */
  232.     {NULL,        (Tcl_CmdProc *) NULL,    (Tcl_ObjCmdProc *) NULL,
  233.         (CompileProc *) NULL,        0}
  234. };
  235.  
  236. /*
  237.  *----------------------------------------------------------------------
  238.  *
  239.  * Tcl_CreateInterp --
  240.  *
  241.  *    Create a new TCL command interpreter.
  242.  *
  243.  * Results:
  244.  *    The return value is a token for the interpreter, which may be
  245.  *    used in calls to procedures like Tcl_CreateCmd, Tcl_Eval, or
  246.  *    Tcl_DeleteInterp.
  247.  *
  248.  * Side effects:
  249.  *    The command interpreter is initialized with an empty variable
  250.  *    table and the built-in commands.
  251.  *
  252.  *----------------------------------------------------------------------
  253.  */
  254.  
  255. Tcl_Interp *
  256. Tcl_CreateInterp()
  257. {
  258.     register Interp *iPtr;
  259.     register Command *cmdPtr;
  260.     register CmdInfo *cmdInfoPtr;
  261.     union {
  262.     char c[sizeof(short)];
  263.     short s;
  264.     } order;
  265.     int i;
  266.  
  267.     /*
  268.      * Panic if someone updated the CallFrame structure without
  269.      * also updating the Tcl_CallFrame structure (or vice versa).
  270.      */  
  271.  
  272.     if (sizeof(Tcl_CallFrame) != sizeof(CallFrame)) {
  273.     /*NOTREACHED*/
  274.         panic("Tcl_CallFrame and CallFrame are not the same size");
  275.     }
  276.  
  277.     /*
  278.      * Initialize support for namespaces and create the global namespace
  279.      * (whose name is ""; an alias is "::"). This also initializes the
  280.      * Tcl object type table and other object management code.
  281.      */
  282.  
  283.     TclInitNamespaces();
  284.     
  285.     iPtr = (Interp *) ckalloc(sizeof(Interp));
  286.     iPtr->result = iPtr->resultSpace;
  287.     iPtr->freeProc = 0;
  288.     iPtr->objResultPtr = Tcl_NewObj(); /* an empty object */
  289.     Tcl_IncrRefCount(iPtr->objResultPtr);
  290.     iPtr->errorLine = 0;
  291.     Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);
  292.     iPtr->numLevels = 0;
  293.     iPtr->maxNestingDepth = 1000;
  294.     iPtr->framePtr = NULL;
  295.     iPtr->varFramePtr = NULL;
  296.     iPtr->activeTracePtr = NULL;
  297.     iPtr->returnCode = TCL_OK;
  298.     iPtr->errorInfo = NULL;
  299.     iPtr->errorCode = NULL;
  300.     iPtr->appendResult = NULL;
  301.     iPtr->appendAvl = 0;
  302.     iPtr->appendUsed = 0;
  303.     for (i = 0; i < NUM_REGEXPS; i++) {
  304.     iPtr->patterns[i] = NULL;
  305.     iPtr->patLengths[i] = -1;
  306.     iPtr->regexps[i] = NULL;
  307.     }
  308.     Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
  309.     iPtr->packageUnknown = NULL;
  310.     iPtr->cmdCount = 0;
  311.     iPtr->termOffset = 0;
  312.     iPtr->compileEpoch = 0;
  313.     iPtr->compiledProcPtr = NULL;
  314.     iPtr->evalFlags = 0;
  315.     iPtr->scriptFile = NULL;
  316.     iPtr->flags = 0;
  317.     iPtr->tracePtr = NULL;
  318.     iPtr->assocData = (Tcl_HashTable *) NULL;
  319.     iPtr->execEnvPtr = NULL;          /* set after namespaces initialized */
  320.     iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
  321.     Tcl_IncrRefCount(iPtr->emptyObjPtr);
  322.     iPtr->resultSpace[0] = 0;
  323.  
  324.     iPtr->globalNsPtr = NULL;    /* force creation of global ns below */
  325.     iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(
  326.         (Tcl_Interp *) iPtr, "", (ClientData) NULL,
  327.         (Tcl_NamespaceDeleteProc *) NULL);
  328.     if (iPtr->globalNsPtr == NULL) {
  329.         panic("Tcl_CreateInterp: can't create global namespace");
  330.     }
  331.  
  332.     /*
  333.      * Initialize support for code compilation. Do this after initializing
  334.      * namespaces since TclCreateExecEnv will try to reference a Tcl
  335.      * variable (it links to the Tcl "tcl_traceExec" variable).
  336.      */
  337.     
  338.     iPtr->execEnvPtr = TclCreateExecEnv((Tcl_Interp *) iPtr);
  339.  
  340.     /*
  341.      * Create the core commands. Do it here, rather than calling
  342.      * Tcl_CreateCommand, because it's faster (there's no need to check for
  343.      * a pre-existing command by the same name). If a command has a
  344.      * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
  345.      * TclInvokeStringCommand. This is an object-based wrapper procedure
  346.      * that extracts strings, calls the string procedure, and creates an
  347.      * object for the result. Similarly, if a command has a Tcl_ObjCmdProc
  348.      * but no Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
  349.      */
  350.  
  351.     for (cmdInfoPtr = builtInCmds;  cmdInfoPtr->name != NULL;
  352.         cmdInfoPtr++) {
  353.     int new;
  354.     Tcl_HashEntry *hPtr;
  355.  
  356.     if ((cmdInfoPtr->proc == (Tcl_CmdProc *) NULL)
  357.             && (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL)
  358.             && (cmdInfoPtr->compileProc == (CompileProc *) NULL)) {
  359.         panic("Tcl_CreateInterp: builtin command with NULL string and object command procs and a NULL compile proc\n");
  360.     }
  361.     
  362.     hPtr = Tcl_CreateHashEntry(&iPtr->globalNsPtr->cmdTable,
  363.             cmdInfoPtr->name, &new);
  364.     if (new) {
  365.         cmdPtr = (Command *) ckalloc(sizeof(Command));
  366.         cmdPtr->hPtr = hPtr;
  367.         cmdPtr->nsPtr = iPtr->globalNsPtr;
  368.         cmdPtr->refCount = 1;
  369.         cmdPtr->cmdEpoch = 0;
  370.         cmdPtr->compileProc = cmdInfoPtr->compileProc;
  371.         if (cmdInfoPtr->proc == (Tcl_CmdProc *) NULL) {
  372.         cmdPtr->proc = TclInvokeObjectCommand;
  373.         cmdPtr->clientData = (ClientData) cmdPtr;
  374.         } else {
  375.         cmdPtr->proc = cmdInfoPtr->proc;
  376.         cmdPtr->clientData = (ClientData) NULL;
  377.         }
  378.         if (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
  379.         cmdPtr->objProc = TclInvokeStringCommand;
  380.         cmdPtr->objClientData = (ClientData) cmdPtr;
  381.         } else {
  382.         cmdPtr->objProc = cmdInfoPtr->objProc;
  383.         cmdPtr->objClientData = (ClientData) NULL;
  384.         }
  385.         cmdPtr->deleteProc = NULL;
  386.         cmdPtr->deleteData = (ClientData) NULL;
  387.         cmdPtr->deleted = 0;
  388.         cmdPtr->importRefPtr = NULL;
  389.         Tcl_SetHashValue(hPtr, cmdPtr);
  390.     }
  391.     }
  392.  
  393.     /*
  394.      *  Initialize/Create "errorInfo" and "errorCode" global vars
  395.      *  (because some part of the C code assume they exists
  396.      *   and we can get a seg fault otherwise (in multiple 
  397.      *   interps loading of extensions for instance) --dl)
  398.      */
  399.      /*
  400.       *  We can't assume that because we initialize 
  401.       *  the variables here, they won't be unset later.
  402.       *  so we had 2 choices:
  403.       *    + Check every place where a GetVar of those is used 
  404.       *      and the NULL result is not checked (like in tclLoad.c)
  405.       *    + Make SetVar,... NULL friendly
  406.       *  We choosed the second option because :
  407.       *    + It is easy and low cost to check for NULL pointer before
  408.       *      calling strlen()
  409.       *    + It can be helpfull to other people using those API
  410.       *    + Passing a NULL value to those closest 'meaning' is empty string
  411.       *      (specially with the new objects where 0 bytes strings are ok)
  412.       * So the following init is commented out:              -- dl
  413.       */
  414.     /*
  415.       (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL, "",
  416.          TCL_GLOBAL_ONLY);
  417.       (void)Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL, "NONE",
  418.         TCL_GLOBAL_ONLY);
  419.      */
  420.  
  421. #ifndef TCL_GENERIC_ONLY
  422.     TclSetupEnv((Tcl_Interp *) iPtr);
  423. #endif
  424.  
  425.     /*
  426.      * Do Multiple/Safe Interps Tcl init stuff
  427.      */
  428.     (void) TclInterpInit((Tcl_Interp *)iPtr);
  429.  
  430.     /*
  431.      * Set up variables such as tcl_version.
  432.      */
  433.  
  434.     TclPlatformInit((Tcl_Interp *)iPtr);
  435.     Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_patchLevel", TCL_PATCH_LEVEL,
  436.         TCL_GLOBAL_ONLY);
  437.     Tcl_SetVar((Tcl_Interp *) iPtr, "tcl_version", TCL_VERSION,
  438.         TCL_GLOBAL_ONLY);
  439.     Tcl_TraceVar2((Tcl_Interp *) iPtr, "tcl_precision", (char *) NULL,
  440.         TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
  441.         TclPrecTraceProc, (ClientData) NULL);
  442.  
  443.     /*
  444.      * Compute the byte order of this machine.
  445.      */
  446.  
  447.     order.s = 1;
  448.     Tcl_SetVar2((Tcl_Interp *) iPtr, "tcl_platform", "byteOrder",
  449.         (order.c[0] == 1) ? "littleEndian" : "bigEndian",
  450.         TCL_GLOBAL_ONLY);
  451.  
  452.     /*
  453.      * Register Tcl's version number.
  454.      */
  455.  
  456.     Tcl_PkgProvide((Tcl_Interp *) iPtr, "Tcl", TCL_VERSION);
  457.     
  458.     return (Tcl_Interp *) iPtr;
  459. }
  460.  
  461. /*
  462.  *----------------------------------------------------------------------
  463.  *
  464.  * TclHideUnsafeCommands --
  465.  *
  466.  *    Hides base commands that are not marked as safe from this
  467.  *    interpreter.
  468.  *
  469.  * Results:
  470.  *    TCL_OK if it succeeds, TCL_ERROR else.
  471.  *
  472.  * Side effects:
  473.  *    Hides functionality in an interpreter.
  474.  *
  475.  *----------------------------------------------------------------------
  476.  */
  477.  
  478. int
  479. TclHideUnsafeCommands(interp)
  480.     Tcl_Interp *interp;        /* Hide commands in this interpreter. */
  481. {
  482.     register CmdInfo *cmdInfoPtr;
  483.  
  484.     if (interp == (Tcl_Interp *) NULL) {
  485.         return TCL_ERROR;
  486.     }
  487.     for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
  488.         if (!cmdInfoPtr->isSafe) {
  489.             Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
  490.         }
  491.     }
  492.     return TCL_OK;
  493. }
  494.  
  495. /*
  496.  *--------------------------------------------------------------
  497.  *
  498.  * Tcl_CallWhenDeleted --
  499.  *
  500.  *    Arrange for a procedure to be called before a given
  501.  *    interpreter is deleted. The procedure is called as soon
  502.  *    as Tcl_DeleteInterp is called; if Tcl_CallWhenDeleted is
  503.  *    called on an interpreter that has already been deleted,
  504.  *    the procedure will be called when the last Tcl_Release is
  505.  *    done on the interpreter.
  506.  *
  507.  * Results:
  508.  *    None.
  509.  *
  510.  * Side effects:
  511.  *    When Tcl_DeleteInterp is invoked to delete interp,
  512.  *    proc will be invoked.  See the manual entry for
  513.  *    details.
  514.  *
  515.  *--------------------------------------------------------------
  516.  */
  517.  
  518. void
  519. Tcl_CallWhenDeleted(interp, proc, clientData)
  520.     Tcl_Interp *interp;        /* Interpreter to watch. */
  521.     Tcl_InterpDeleteProc *proc;    /* Procedure to call when interpreter
  522.                  * is about to be deleted. */
  523.     ClientData clientData;    /* One-word value to pass to proc. */
  524. {
  525.     Interp *iPtr = (Interp *) interp;
  526.     static int assocDataCounter = 0;
  527.     int new;
  528.     char buffer[128];
  529.     AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
  530.     Tcl_HashEntry *hPtr;
  531.  
  532.     sprintf(buffer, "Assoc Data Key #%d", assocDataCounter);
  533.     assocDataCounter++;
  534.  
  535.     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
  536.         iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
  537.         Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
  538.     }
  539.     hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
  540.     dPtr->proc = proc;
  541.     dPtr->clientData = clientData;
  542.     Tcl_SetHashValue(hPtr, dPtr);
  543. }
  544.  
  545. /*
  546.  *--------------------------------------------------------------
  547.  *
  548.  * Tcl_DontCallWhenDeleted --
  549.  *
  550.  *    Cancel the arrangement for a procedure to be called when
  551.  *    a given interpreter is deleted.
  552.  *
  553.  * Results:
  554.  *    None.
  555.  *
  556.  * Side effects:
  557.  *    If proc and clientData were previously registered as a
  558.  *    callback via Tcl_CallWhenDeleted, they are unregistered.
  559.  *    If they weren't previously registered then nothing
  560.  *    happens.
  561.  *
  562.  *--------------------------------------------------------------
  563.  */
  564.  
  565. void
  566. Tcl_DontCallWhenDeleted(interp, proc, clientData)
  567.     Tcl_Interp *interp;        /* Interpreter to watch. */
  568.     Tcl_InterpDeleteProc *proc;    /* Procedure to call when interpreter
  569.                  * is about to be deleted. */
  570.     ClientData clientData;    /* One-word value to pass to proc. */
  571. {
  572.     Interp *iPtr = (Interp *) interp;
  573.     Tcl_HashTable *hTablePtr;
  574.     Tcl_HashSearch hSearch;
  575.     Tcl_HashEntry *hPtr;
  576.     AssocData *dPtr;
  577.  
  578.     hTablePtr = iPtr->assocData;
  579.     if (hTablePtr == (Tcl_HashTable *) NULL) {
  580.         return;
  581.     }
  582.     for (hPtr = Tcl_FirstHashEntry(hTablePtr, &hSearch); hPtr != NULL;
  583.         hPtr = Tcl_NextHashEntry(&hSearch)) {
  584.         dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  585.         if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
  586.             ckfree((char *) dPtr);
  587.             Tcl_DeleteHashEntry(hPtr);
  588.             return;
  589.         }
  590.     }
  591. }
  592.  
  593. /*
  594.  *----------------------------------------------------------------------
  595.  *
  596.  * Tcl_SetAssocData --
  597.  *
  598.  *    Creates a named association between user-specified data, a delete
  599.  *    function and this interpreter. If the association already exists
  600.  *    the data is overwritten with the new data. The delete function will
  601.  *    be invoked when the interpreter is deleted.
  602.  *
  603.  * Results:
  604.  *    None.
  605.  *
  606.  * Side effects:
  607.  *    Sets the associated data, creates the association if needed.
  608.  *
  609.  *----------------------------------------------------------------------
  610.  */
  611.  
  612. void
  613. Tcl_SetAssocData(interp, name, proc, clientData)
  614.     Tcl_Interp *interp;        /* Interpreter to associate with. */
  615.     char *name;            /* Name for association. */
  616.     Tcl_InterpDeleteProc *proc;    /* Proc to call when interpreter is
  617.                                  * about to be deleted. */
  618.     ClientData clientData;    /* One-word value to pass to proc. */
  619. {
  620.     Interp *iPtr = (Interp *) interp;
  621.     AssocData *dPtr;
  622.     Tcl_HashEntry *hPtr;
  623.     int new;
  624.  
  625.     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
  626.         iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
  627.         Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
  628.     }
  629.     hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &new);
  630.     if (new == 0) {
  631.         dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  632.     } else {
  633.         dPtr = (AssocData *) ckalloc(sizeof(AssocData));
  634.     }
  635.     dPtr->proc = proc;
  636.     dPtr->clientData = clientData;
  637.  
  638.     Tcl_SetHashValue(hPtr, dPtr);
  639. }
  640.  
  641. /*
  642.  *----------------------------------------------------------------------
  643.  *
  644.  * Tcl_DeleteAssocData --
  645.  *
  646.  *    Deletes a named association of user-specified data with
  647.  *    the specified interpreter.
  648.  *
  649.  * Results:
  650.  *    None.
  651.  *
  652.  * Side effects:
  653.  *    Deletes the association.
  654.  *
  655.  *----------------------------------------------------------------------
  656.  */
  657.  
  658. void
  659. Tcl_DeleteAssocData(interp, name)
  660.     Tcl_Interp *interp;            /* Interpreter to associate with. */
  661.     char *name;                /* Name of association. */
  662. {
  663.     Interp *iPtr = (Interp *) interp;
  664.     AssocData *dPtr;
  665.     Tcl_HashEntry *hPtr;
  666.  
  667.     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
  668.         return;
  669.     }
  670.     hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
  671.     if (hPtr == (Tcl_HashEntry *) NULL) {
  672.         return;
  673.     }
  674.     dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  675.     if (dPtr->proc != NULL) {
  676.         (dPtr->proc) (dPtr->clientData, interp);
  677.     }
  678.     ckfree((char *) dPtr);
  679.     Tcl_DeleteHashEntry(hPtr);
  680. }
  681.  
  682. /*
  683.  *----------------------------------------------------------------------
  684.  *
  685.  * Tcl_GetAssocData --
  686.  *
  687.  *    Returns the client data associated with this name in the
  688.  *    specified interpreter.
  689.  *
  690.  * Results:
  691.  *    The client data in the AssocData record denoted by the named
  692.  *    association, or NULL.
  693.  *
  694.  * Side effects:
  695.  *    None.
  696.  *
  697.  *----------------------------------------------------------------------
  698.  */
  699.  
  700. ClientData
  701. Tcl_GetAssocData(interp, name, procPtr)
  702.     Tcl_Interp *interp;            /* Interpreter associated with. */
  703.     char *name;                /* Name of association. */
  704.     Tcl_InterpDeleteProc **procPtr;    /* Pointer to place to store address
  705.                      * of current deletion callback. */
  706. {
  707.     Interp *iPtr = (Interp *) interp;
  708.     AssocData *dPtr;
  709.     Tcl_HashEntry *hPtr;
  710.  
  711.     if (iPtr->assocData == (Tcl_HashTable *) NULL) {
  712.         return (ClientData) NULL;
  713.     }
  714.     hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
  715.     if (hPtr == (Tcl_HashEntry *) NULL) {
  716.         return (ClientData) NULL;
  717.     }
  718.     dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  719.     if (procPtr != (Tcl_InterpDeleteProc **) NULL) {
  720.         *procPtr = dPtr->proc;
  721.     }
  722.     return dPtr->clientData;
  723. }
  724.  
  725. /*
  726.  *----------------------------------------------------------------------
  727.  *
  728.  * DeleteInterpProc --
  729.  *
  730.  *    Helper procedure to delete an interpreter. This procedure is
  731.  *    called when the last call to Tcl_Preserve on this interpreter
  732.  *    is matched by a call to Tcl_Release. The procedure cleans up
  733.  *    all resources used in the interpreter and calls all currently
  734.  *    registered interpreter deletion callbacks.
  735.  *
  736.  * Results:
  737.  *    None.
  738.  *
  739.  * Side effects:
  740.  *    Whatever the interpreter deletion callbacks do. Frees resources
  741.  *    used by the interpreter.
  742.  *
  743.  *----------------------------------------------------------------------
  744.  */
  745.  
  746. static void
  747. DeleteInterpProc(interp)
  748.     Tcl_Interp *interp;            /* Interpreter to delete. */
  749. {
  750.     Interp *iPtr = (Interp *) interp;
  751.     Tcl_HashEntry *hPtr;
  752.     Tcl_HashSearch search;
  753.     Tcl_HashTable *hTablePtr;
  754.     AssocData *dPtr;
  755.     int i;
  756.  
  757.     /*
  758.      * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
  759.      */
  760.     
  761.     if (iPtr->numLevels > 0) {
  762.         panic("DeleteInterpProc called with active evals");
  763.     }
  764.  
  765.     /*
  766.      * The interpreter should already be marked deleted; otherwise how
  767.      * did we get here?
  768.      */
  769.  
  770.     if (!(iPtr->flags & DELETED)) {
  771.         panic("DeleteInterpProc called on interpreter not marked deleted");
  772.     }
  773.  
  774.     /*
  775.      * Dismantle everything in the global namespace except for the
  776.      * "errorInfo" and "errorCode" variables. These remain until the
  777.      * namespace is actually destroyed, in case any errors occur.
  778.      *   
  779.      * Dismantle the namespace here, before we clear the assocData. If any
  780.      * background errors occur here, they will be deleted below.
  781.      */
  782.     
  783.     TclTeardownNamespace(iPtr->globalNsPtr);
  784.  
  785.     /*
  786.      * Tear down the math function table.
  787.      */
  788.  
  789.     for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
  790.          hPtr != NULL;
  791.              hPtr = Tcl_NextHashEntry(&search)) {
  792.     ckfree((char *) Tcl_GetHashValue(hPtr));
  793.     }
  794.     Tcl_DeleteHashTable(&iPtr->mathFuncTable);
  795.  
  796.     /*
  797.      * Invoke deletion callbacks; note that a callback can create new
  798.      * callbacks, so we iterate.
  799.      */
  800.  
  801.     while (iPtr->assocData != (Tcl_HashTable *) NULL) {
  802.         hTablePtr = iPtr->assocData;
  803.         iPtr->assocData = (Tcl_HashTable *) NULL;
  804.         for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
  805.                  hPtr != NULL;
  806.                  hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
  807.             dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
  808.             Tcl_DeleteHashEntry(hPtr);
  809.             if (dPtr->proc != NULL) {
  810.                 (*dPtr->proc)(dPtr->clientData, interp);
  811.             }
  812.             ckfree((char *) dPtr);
  813.         }
  814.         Tcl_DeleteHashTable(hTablePtr);
  815.         ckfree((char *) hTablePtr);
  816.     }
  817.  
  818.     /*
  819.      * Finish deleting the global namespace.
  820.      */
  821.     
  822.     Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
  823.  
  824.     /*
  825.      * Free up the result *after* deleting variables, since variable
  826.      * deletion could have transferred ownership of the result string
  827.      * to Tcl.
  828.      */
  829.  
  830.     Tcl_FreeResult(interp);
  831.     interp->result = NULL;
  832.     Tcl_DecrRefCount(iPtr->objResultPtr);
  833.     iPtr->objResultPtr = NULL;
  834.     if (iPtr->errorInfo != NULL) {
  835.     ckfree(iPtr->errorInfo);
  836.         iPtr->errorInfo = NULL;
  837.     }
  838.     if (iPtr->errorCode != NULL) {
  839.     ckfree(iPtr->errorCode);
  840.         iPtr->errorCode = NULL;
  841.     }
  842.     if (iPtr->appendResult != NULL) {
  843.     ckfree(iPtr->appendResult);
  844.         iPtr->appendResult = NULL;
  845.     }
  846.     for (i = 0; i < NUM_REGEXPS; i++) {
  847.     if (iPtr->patterns[i] == NULL) {
  848.         break;
  849.     }
  850.     ckfree(iPtr->patterns[i]);
  851.     ckfree((char *) iPtr->regexps[i]);
  852.         iPtr->regexps[i] = NULL;
  853.     }
  854.     TclFreePackageInfo(iPtr);
  855.     while (iPtr->tracePtr != NULL) {
  856.     Trace *nextPtr = iPtr->tracePtr->nextPtr;
  857.  
  858.     ckfree((char *) iPtr->tracePtr);
  859.     iPtr->tracePtr = nextPtr;
  860.     }
  861.     if (iPtr->execEnvPtr != NULL) {
  862.     TclDeleteExecEnv(iPtr->execEnvPtr);
  863.     }
  864.     Tcl_DecrRefCount(iPtr->emptyObjPtr);
  865.     iPtr->emptyObjPtr = NULL;
  866.     
  867.     ckfree((char *) iPtr);
  868. }
  869.  
  870. /*
  871.  *----------------------------------------------------------------------
  872.  *
  873.  * Tcl_InterpDeleted --
  874.  *
  875.  *    Returns nonzero if the interpreter has been deleted with a call
  876.  *    to Tcl_DeleteInterp.
  877.  *
  878.  * Results:
  879.  *    Nonzero if the interpreter is deleted, zero otherwise.
  880.  *
  881.  * Side effects:
  882.  *    None.
  883.  *
  884.  *----------------------------------------------------------------------
  885.  */
  886.  
  887. int
  888. Tcl_InterpDeleted(interp)
  889.     Tcl_Interp *interp;
  890. {
  891.     return (((Interp *) interp)->flags & DELETED) ? 1 : 0;
  892. }
  893.  
  894. /*
  895.  *----------------------------------------------------------------------
  896.  *
  897.  * Tcl_DeleteInterp --
  898.  *
  899.  *    Ensures that the interpreter will be deleted eventually. If there
  900.  *    are no Tcl_Preserve calls in effect for this interpreter, it is
  901.  *    deleted immediately, otherwise the interpreter is deleted when
  902.  *    the last Tcl_Preserve is matched by a call to Tcl_Release. In either
  903.  *    case, the procedure runs the currently registered deletion callbacks. 
  904.  *
  905.  * Results:
  906.  *    None.
  907.  *
  908.  * Side effects:
  909.  *    The interpreter is marked as deleted. The caller may still use it
  910.  *    safely if there are calls to Tcl_Preserve in effect for the
  911.  *    interpreter, but further calls to Tcl_Eval etc in this interpreter
  912.  *    will fail.
  913.  *
  914.  *----------------------------------------------------------------------
  915.  */
  916.  
  917. void
  918. Tcl_DeleteInterp(interp)
  919.     Tcl_Interp *interp;        /* Token for command interpreter (returned
  920.                  * by a previous call to Tcl_CreateInterp). */
  921. {
  922.     Interp *iPtr = (Interp *) interp;
  923.  
  924.     /*
  925.      * If the interpreter has already been marked deleted, just punt.
  926.      */
  927.  
  928.     if (iPtr->flags & DELETED) {
  929.         return;
  930.     }
  931.     
  932.     /*
  933.      * Mark the interpreter as deleted. No further evals will be allowed.
  934.      */
  935.  
  936.     iPtr->flags |= DELETED;
  937.  
  938.     /*
  939.      * Ensure that the interpreter is eventually deleted.
  940.      */
  941.  
  942.     Tcl_EventuallyFree((ClientData) interp,
  943.             (Tcl_FreeProc *) DeleteInterpProc);
  944. }
  945.  
  946. /*
  947.  *----------------------------------------------------------------------
  948.  *
  949.  * HiddenCmdsDeleteProc --
  950.  *
  951.  *    Called on interpreter deletion to delete all the hidden
  952.  *    commands in an interpreter.
  953.  *
  954.  * Results:
  955.  *    None.
  956.  *
  957.  * Side effects:
  958.  *    Frees up memory.
  959.  *
  960.  *----------------------------------------------------------------------
  961.  */
  962.  
  963. static void
  964. HiddenCmdsDeleteProc(clientData, interp)
  965.     ClientData clientData;        /* The hidden commands hash table. */
  966.     Tcl_Interp *interp;            /* The interpreter being deleted. */
  967. {
  968.     Tcl_HashTable *hiddenCmdTblPtr;
  969.     Tcl_HashEntry *hPtr;
  970.     Tcl_HashSearch hSearch;
  971.     Command *cmdPtr;
  972.  
  973.     hiddenCmdTblPtr = (Tcl_HashTable *) clientData;
  974.     for (hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch);
  975.          hPtr != NULL;
  976.              hPtr = Tcl_FirstHashEntry(hiddenCmdTblPtr, &hSearch)) {
  977.  
  978.         /*
  979.          * Cannot use Tcl_DeleteCommand because (a) the command is not
  980.          * in the command hash table, and (b) that table has already been
  981.          * deleted above. Hence we emulate what it does, below.
  982.          */
  983.         
  984.         cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  985.  
  986.     /*
  987.          * The code here is tricky.  We can't delete the hash table entry
  988.          * before invoking the deletion callback because there are cases
  989.          * where the deletion callback needs to invoke the command (e.g.
  990.          * object systems such as OTcl).  However, this means that the
  991.          * callback could try to delete or rename the command.  The deleted
  992.          * flag allows us to detect these cases and skip nested deletes.
  993.          */
  994.  
  995.         if (cmdPtr->deleted) {
  996.  
  997.         /*
  998.              * Another deletion is already in progress.  Remove the hash
  999.              * table entry now, but don't invoke a callback or free the
  1000.              * command structure.
  1001.              */
  1002.  
  1003.             Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1004.             cmdPtr->hPtr = NULL;
  1005.             continue;
  1006.         }
  1007.         cmdPtr->deleted = 1;
  1008.         if (cmdPtr->deleteProc != NULL) {
  1009.             (*cmdPtr->deleteProc)(cmdPtr->deleteData);
  1010.         }
  1011.  
  1012.     /*
  1013.      * Bump the command epoch counter. This will invalidate all cached
  1014.          * references that refer to this command.
  1015.      */
  1016.     
  1017.         cmdPtr->cmdEpoch++;
  1018.  
  1019.     /*
  1020.          * Don't use hPtr to delete the hash entry here, because it's
  1021.          * possible that the deletion callback renamed the command.
  1022.          * Instead, use cmdPtr->hptr, and make sure that no-one else
  1023.          * has already deleted the hash entry.
  1024.          */
  1025.  
  1026.         if (cmdPtr->hPtr != NULL) {
  1027.             Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1028.         }
  1029.     
  1030.         /*
  1031.      * Now free the Command structure, unless there is another reference
  1032.      * to it from a CmdName Tcl object in some ByteCode code
  1033.      * sequence. In that case, delay the cleanup until all references
  1034.      * are either discarded (when a ByteCode is freed) or replaced by a
  1035.      * new reference (when a cached CmdName Command reference is found
  1036.      * to be invalid and TclExecuteByteCode looks up the command in the
  1037.      * command hashtable).
  1038.      */
  1039.     
  1040.     TclCleanupCommand(cmdPtr);
  1041.     }
  1042.     Tcl_DeleteHashTable(hiddenCmdTblPtr);
  1043.     ckfree((char *) hiddenCmdTblPtr);
  1044. }
  1045.  
  1046. /*
  1047.  *----------------------------------------------------------------------
  1048.  *
  1049.  * Tcl_HideCommand --
  1050.  *
  1051.  *    Makes a command hidden so that it cannot be invoked from within
  1052.  *    an interpreter, only from within an ancestor.
  1053.  *
  1054.  * Results:
  1055.  *    A standard Tcl result; also leaves a message in interp->result
  1056.  *    if an error occurs.
  1057.  *
  1058.  * Side effects:
  1059.  *    Removes a command from the command table and create an entry
  1060.  *      into the hidden command table under the specified token name.
  1061.  *
  1062.  *----------------------------------------------------------------------
  1063.  */
  1064.  
  1065. int
  1066. Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
  1067.     Tcl_Interp *interp;        /* Interpreter in which to hide command. */
  1068.     char *cmdName;        /* Name of command to hide. */
  1069.     char *hiddenCmdToken;    /* Token name of the to-be-hidden command. */
  1070. {
  1071.     Interp *iPtr = (Interp *) interp;
  1072.     Tcl_Command cmd;
  1073.     Command *cmdPtr;
  1074.     Tcl_HashTable *hTblPtr;
  1075.     Tcl_HashEntry *hPtr;
  1076.     int new;
  1077.  
  1078.     if (iPtr->flags & DELETED) {
  1079.  
  1080.         /*
  1081.          * The interpreter is being deleted. Do not create any new
  1082.          * structures, because it is not safe to modify the interpreter.
  1083.          */
  1084.         
  1085.         return TCL_ERROR;
  1086.     }
  1087.  
  1088.     /*
  1089.      * Disallow hiding of commands that are currently in a namespace or
  1090.      * renaming (as part of hiding) into a namespace.
  1091.      *
  1092.      * (because the current implementation with a single global table
  1093.      *  and the needed uniqueness of names cause problems with namespaces)
  1094.      *
  1095.      * we don't need to check for "::" in cmdName because the real check is
  1096.      * on the nsPtr below.
  1097.      *
  1098.      * hiddenCmdToken is just a string which is not interpreted in any way.
  1099.      * It may contain :: but the string is not interpreted as a namespace
  1100.      * qualifier command name. Thus, hiding foo::bar to foo::bar and then
  1101.      * trying to expose or invoke ::foo::bar will NOT work; but if the
  1102.      * application always uses the same strings it will get consistent
  1103.      * behaviour.
  1104.      *
  1105.      * But as we currently limit ourselves to the global namespace only
  1106.      * for the source, in order to avoid potential confusion,
  1107.      * lets prevent "::" in the token too.  --dl
  1108.      */
  1109.  
  1110.     if (strstr(hiddenCmdToken, "::") != NULL) {
  1111.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1112.                 "cannot use namespace qualifiers as hidden command",
  1113.         "token (rename)", (char *) NULL);
  1114.         return TCL_ERROR;
  1115.     }
  1116.  
  1117.     /*
  1118.      * Find the command to hide. An error is returned if cmdName can't
  1119.      * be found. Look up the command only from the global namespace.
  1120.      * Full path of the command must be given if using namespaces.
  1121.      */
  1122.  
  1123.     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  1124.         /*flags*/ TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
  1125.     if (cmd == (Tcl_Command) NULL) {
  1126.     return TCL_ERROR;
  1127.     }
  1128.     cmdPtr = (Command *) cmd;
  1129.  
  1130.     /*
  1131.      * Check that the command is really in global namespace
  1132.      */
  1133.  
  1134.     if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
  1135.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1136.                 "can only hide global namespace commands",
  1137.         " (use rename then hide)", (char *) NULL);
  1138.         return TCL_ERROR;
  1139.     }
  1140.     
  1141.     /*
  1142.      * Initialize the hidden command table if necessary.
  1143.      */
  1144.  
  1145.     hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
  1146.             NULL);
  1147.     if (hTblPtr == (Tcl_HashTable *) NULL) {
  1148.         hTblPtr = (Tcl_HashTable *)
  1149.             ckalloc((unsigned) sizeof(Tcl_HashTable));
  1150.         Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);
  1151.         Tcl_SetAssocData(interp, "tclHiddenCmds", HiddenCmdsDeleteProc,
  1152.                 (ClientData) hTblPtr);
  1153.     }
  1154.  
  1155.     /*
  1156.      * It is an error to move an exposed command to a hidden command with
  1157.      * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
  1158.      * exists.
  1159.      */
  1160.     
  1161.     hPtr = Tcl_CreateHashEntry(hTblPtr, hiddenCmdToken, &new);
  1162.     if (!new) {
  1163.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1164.                 "hidden command named \"", hiddenCmdToken, "\" already exists",
  1165.                 (char *) NULL);
  1166.         return TCL_ERROR;
  1167.     }
  1168.  
  1169.     /*
  1170.      * Nb : This code is currently 'like' a rename to a specialy set apart
  1171.      * name table. Changes here and in TclRenameCommand must
  1172.      * be kept in synch untill the common parts are actually
  1173.      * factorized out.
  1174.      */
  1175.  
  1176.     /*
  1177.      * Remove the hash entry for the command from the interpreter command
  1178.      * table. This is like deleting the command, so bump its command epoch;
  1179.      * this invalidates any cached references that point to the command.
  1180.      */
  1181.  
  1182.     if (cmdPtr->hPtr != NULL) {
  1183.         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1184.         cmdPtr->hPtr = (Tcl_HashEntry *) NULL;
  1185.     cmdPtr->cmdEpoch++;
  1186.     }
  1187.  
  1188.     /*
  1189.      * Now link the hash table entry with the command structure.
  1190.      * We ensured above that the nsPtr was right.
  1191.      */
  1192.     
  1193.     cmdPtr->hPtr = hPtr;
  1194.     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  1195.  
  1196.     /*
  1197.      * If the command being hidden has a compile procedure, increment the
  1198.      * interpreter's compileEpoch to invalidate its compiled code. This
  1199.      * makes sure that we don't later try to execute old code compiled with
  1200.      * command-specific (i.e., inline) bytecodes for the now-hidden
  1201.      * command. This field is checked in Tcl_EvalObj and ObjInterpProc,
  1202.      * and code whose compilation epoch doesn't match is recompiled.
  1203.      */
  1204.  
  1205.     if (cmdPtr->compileProc != NULL) {
  1206.     iPtr->compileEpoch++;
  1207.     }
  1208.     return TCL_OK;
  1209. }
  1210.  
  1211. /*
  1212.  *----------------------------------------------------------------------
  1213.  *
  1214.  * Tcl_ExposeCommand --
  1215.  *
  1216.  *    Makes a previously hidden command callable from inside the
  1217.  *    interpreter instead of only by its ancestors.
  1218.  *
  1219.  * Results:
  1220.  *    A standard Tcl result. If an error occurs, a message is left
  1221.  *    in interp->result.
  1222.  *
  1223.  * Side effects:
  1224.  *    Moves commands from one hash table to another.
  1225.  *
  1226.  *----------------------------------------------------------------------
  1227.  */
  1228.  
  1229. int
  1230. Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
  1231.     Tcl_Interp *interp;        /* Interpreter in which to make command
  1232.                                  * callable. */
  1233.     char *hiddenCmdToken;    /* Name of hidden command. */
  1234.     char *cmdName;        /* Name of to-be-exposed command. */
  1235. {
  1236.     Interp *iPtr = (Interp *) interp;
  1237.     Command *cmdPtr;
  1238.     Namespace *nsPtr;
  1239.     Tcl_HashEntry *hPtr;
  1240.     Tcl_HashTable *hTblPtr;
  1241.     int new;
  1242.  
  1243.     if (iPtr->flags & DELETED) {
  1244.         /*
  1245.          * The interpreter is being deleted. Do not create any new
  1246.          * structures, because it is not safe to modify the interpreter.
  1247.          */
  1248.         
  1249.         return TCL_ERROR;
  1250.     }
  1251.  
  1252.     /*
  1253.      * Check that we have a regular name for the command
  1254.      * (that the user is not trying to do an expose and a rename
  1255.      *  (to another namespace) at the same time)
  1256.      */
  1257.  
  1258.     if (strstr(cmdName, "::") != NULL) {
  1259.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1260.                 "can not expose to a namespace ",
  1261.         "(use expose to toplevel, then rename)",
  1262.                  (char *) NULL);
  1263.         return TCL_ERROR;
  1264.     }
  1265.  
  1266.     /*
  1267.      * Find the hash table for the hidden commands; error out if there
  1268.      * is none.
  1269.      */
  1270.  
  1271.     hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclHiddenCmds",
  1272.             NULL);
  1273.     if (hTblPtr == NULL) {
  1274.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1275.                 "unknown hidden command \"", hiddenCmdToken,
  1276.                 "\"", (char *) NULL);
  1277.         return TCL_ERROR;
  1278.     }
  1279.         
  1280.     /*
  1281.      * Get the command from the hidden command table:
  1282.      */
  1283.  
  1284.     hPtr = Tcl_FindHashEntry(hTblPtr, hiddenCmdToken);
  1285.     if (hPtr == (Tcl_HashEntry *) NULL) {
  1286.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1287.                 "unknown hidden command \"", hiddenCmdToken,
  1288.                 "\"", (char *) NULL);
  1289.         return TCL_ERROR;
  1290.     }
  1291.     cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1292.     
  1293.  
  1294.     /*
  1295.      * Check that we have a true global namespace
  1296.      * command (enforced by Tcl_HideCommand() but let's double
  1297.      * check. (If it was not, we would not really know how to
  1298.      * handle it).
  1299.      */
  1300.     if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
  1301.     /* 
  1302.      * This case is theoritically impossible,
  1303.      * we might rather panic() than 'nicely' erroring out ?
  1304.      */
  1305.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1306.                 "trying to expose a non global command name space command",
  1307.         (char *) NULL);
  1308.         return TCL_ERROR;
  1309.     }
  1310.     
  1311.     /* This is the global table */
  1312.     nsPtr = cmdPtr->nsPtr;
  1313.  
  1314.     /*
  1315.      * It is an error to overwrite an existing exposed command as a result
  1316.      * of exposing a previously hidden command.
  1317.      */
  1318.  
  1319.     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &new);
  1320.     if (!new) {
  1321.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1322.                 "exposed command \"", cmdName,
  1323.                 "\" already exists", (char *) NULL);
  1324.         return TCL_ERROR;
  1325.     }
  1326.  
  1327.     /*
  1328.      * Remove the hash entry for the command from the interpreter hidden
  1329.      * command table.
  1330.      */
  1331.  
  1332.     if (cmdPtr->hPtr != NULL) {
  1333.         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1334.         cmdPtr->hPtr = NULL;
  1335.     }
  1336.  
  1337.     /*
  1338.      * Now link the hash table entry with the command structure.
  1339.      * This is like creating a new command, so deal with any shadowing
  1340.      * of commands in the global namespace.
  1341.      */
  1342.     
  1343.     cmdPtr->hPtr = hPtr;
  1344.  
  1345.     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  1346.  
  1347.     /*
  1348.      * Not needed as we are only in the global namespace
  1349.      * (but would be needed again if we supported namespace command hiding)
  1350.      *
  1351.      * TclResetShadowedCmdRefs(interp, cmdPtr);
  1352.      */
  1353.  
  1354.  
  1355.     /*
  1356.      * If the command being exposed has a compile procedure, increment
  1357.      * interpreter's compileEpoch to invalidate its compiled code. This
  1358.      * makes sure that we don't later try to execute old code compiled
  1359.      * assuming the command is hidden. This field is checked in Tcl_EvalObj
  1360.      * and ObjInterpProc, and code whose compilation epoch doesn't match is
  1361.      * recompiled.
  1362.      */
  1363.  
  1364.     if (cmdPtr->compileProc != NULL) {
  1365.     iPtr->compileEpoch++;
  1366.     }
  1367.     return TCL_OK;
  1368. }
  1369.  
  1370. /*
  1371.  *----------------------------------------------------------------------
  1372.  *
  1373.  * Tcl_CreateCommand --
  1374.  *
  1375.  *    Define a new command in a command table.
  1376.  *
  1377.  * Results:
  1378.  *    The return value is a token for the command, which can
  1379.  *    be used in future calls to Tcl_GetCommandName.
  1380.  *
  1381.  * Side effects:
  1382.  *    If a command named cmdName already exists for interp, it is deleted.
  1383.  *    In the future, when cmdName is seen as the name of a command by
  1384.  *    Tcl_Eval, proc will be called. To support the bytecode interpreter,
  1385.  *    the command is created with a wrapper Tcl_ObjCmdProc
  1386.  *    (TclInvokeStringCommand) that eventially calls proc. When the
  1387.  *    command is deleted from the table, deleteProc will be called.
  1388.  *    See the manual entry for details on the calling sequence.
  1389.  *
  1390.  *----------------------------------------------------------------------
  1391.  */
  1392.  
  1393. Tcl_Command
  1394. Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
  1395.     Tcl_Interp *interp;        /* Token for command interpreter returned by
  1396.                  * a previous call to Tcl_CreateInterp. */
  1397.     char *cmdName;        /* Name of command. If it contains namespace
  1398.                  * qualifiers, the new command is put in the
  1399.                  * specified namespace; otherwise it is put
  1400.                  * in the global namespace. */
  1401.     Tcl_CmdProc *proc;        /* Procedure to associate with cmdName. */
  1402.     ClientData clientData;    /* Arbitrary value passed to string proc. */
  1403.     Tcl_CmdDeleteProc *deleteProc;
  1404.                 /* If not NULL, gives a procedure to call
  1405.                  * when this command is deleted. */
  1406. {
  1407.     Interp *iPtr = (Interp *) interp;
  1408.     Namespace *nsPtr, *dummy1, *dummy2;
  1409.     Command *cmdPtr;
  1410.     Tcl_HashEntry *hPtr;
  1411.     char *tail;
  1412.     int new, result;
  1413.  
  1414.     if (iPtr->flags & DELETED) {
  1415.     /*
  1416.      * The interpreter is being deleted.  Don't create any new
  1417.      * commands; it's not safe to muck with the interpreter anymore.
  1418.      */
  1419.  
  1420.     return (Tcl_Command) NULL;
  1421.     }
  1422.  
  1423.     /*
  1424.      * Determine where the command should reside. If its name contains 
  1425.      * namespace qualifiers, we put it in the specified namespace; 
  1426.      * otherwise, we always put it in the global namespace.
  1427.      */
  1428.  
  1429.     if (strstr(cmdName, "::") != NULL) {
  1430.     result = TclGetNamespaceForQualName(interp, cmdName, 
  1431.                 (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr, 
  1432.                 &dummy1, &dummy2, &tail);
  1433.     if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
  1434.         return (Tcl_Command) NULL;
  1435.     }
  1436.     } else {
  1437.     nsPtr = iPtr->globalNsPtr;
  1438.     tail = cmdName;
  1439.     }
  1440.     
  1441.     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1442.     if (!new) {
  1443.     /*
  1444.      * Command already exists. Delete the old one.
  1445.      */
  1446.  
  1447.     cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1448.     Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
  1449.     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1450.     if (!new) {
  1451.         /*
  1452.          * If the deletion callback recreated the command, just throw
  1453.              * away the new command (if we try to delete it again, we
  1454.              * could get stuck in an infinite loop).
  1455.          */
  1456.  
  1457.          ckfree((char*) cmdPtr);
  1458.     }
  1459.     }
  1460.     cmdPtr = (Command *) ckalloc(sizeof(Command));
  1461.     Tcl_SetHashValue(hPtr, cmdPtr);
  1462.     cmdPtr->hPtr = hPtr;
  1463.     cmdPtr->nsPtr = nsPtr;
  1464.     cmdPtr->refCount = 1;
  1465.     cmdPtr->cmdEpoch = 0;
  1466.     cmdPtr->compileProc = (CompileProc *) NULL;
  1467.     cmdPtr->objProc = TclInvokeStringCommand;
  1468.     cmdPtr->objClientData = (ClientData) cmdPtr;
  1469.     cmdPtr->proc = proc;
  1470.     cmdPtr->clientData = clientData;
  1471.     cmdPtr->deleteProc = deleteProc;
  1472.     cmdPtr->deleteData = clientData;
  1473.     cmdPtr->deleted = 0;
  1474.     cmdPtr->importRefPtr = NULL;
  1475.  
  1476.     /*
  1477.      * We just created a command, so in its namespace and all of its parent
  1478.      * namespaces, it may shadow global commands with the same name. If any
  1479.      * shadowed commands are found, invalidate all cached command references
  1480.      * in the affected namespaces.
  1481.      */
  1482.     
  1483.     TclResetShadowedCmdRefs(interp, cmdPtr);
  1484.     return (Tcl_Command) cmdPtr;
  1485. }
  1486.  
  1487. /*
  1488.  *----------------------------------------------------------------------
  1489.  *
  1490.  * Tcl_CreateObjCommand --
  1491.  *
  1492.  *    Define a new object-based command in a command table.
  1493.  *
  1494.  * Results:
  1495.  *    The return value is a token for the command, which can
  1496.  *    be used in future calls to Tcl_NameOfCommand.
  1497.  *
  1498.  * Side effects:
  1499.  *    If no command named "cmdName" already exists for interp, one is
  1500.  *    created. Otherwise, if a command does exist, then if the
  1501.  *    object-based Tcl_ObjCmdProc is TclInvokeStringCommand, we assume
  1502.  *    Tcl_CreateCommand was called previously for the same command and
  1503.  *    just set its Tcl_ObjCmdProc to the argument "proc"; otherwise, we
  1504.  *    delete the old command.
  1505.  *
  1506.  *    In the future, during bytecode evaluation when "cmdName" is seen as
  1507.  *    the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
  1508.  *    Tcl_ObjCmdProc proc will be called. When the command is deleted from
  1509.  *    the table, deleteProc will be called. See the manual entry for
  1510.  *    details on the calling sequence.
  1511.  *
  1512.  *----------------------------------------------------------------------
  1513.  */
  1514.  
  1515. Tcl_Command
  1516. Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
  1517.     Tcl_Interp *interp;        /* Token for command interpreter (returned
  1518.                  * by previous call to Tcl_CreateInterp). */
  1519.     char *cmdName;        /* Name of command. If it contains namespace
  1520.                  * qualifiers, the new command is put in the
  1521.                  * specified namespace; otherwise it is put
  1522.                  * in the global namespace. */
  1523.     Tcl_ObjCmdProc *proc;    /* Object-based procedure to associate with
  1524.                  * name. */
  1525.     ClientData clientData;    /* Arbitrary value to pass to object
  1526.                      * procedure. */
  1527.     Tcl_CmdDeleteProc *deleteProc;
  1528.                 /* If not NULL, gives a procedure to call
  1529.                  * when this command is deleted. */
  1530. {
  1531.     Interp *iPtr = (Interp *) interp;
  1532.     Namespace *nsPtr, *dummy1, *dummy2;
  1533.     Command *cmdPtr;
  1534.     Tcl_HashEntry *hPtr;
  1535.     char *tail;
  1536.     int new, result;
  1537.  
  1538.     if (iPtr->flags & DELETED) {
  1539.     /*
  1540.      * The interpreter is being deleted.  Don't create any new
  1541.      * commands;  it's not safe to muck with the interpreter anymore.
  1542.      */
  1543.  
  1544.     return (Tcl_Command) NULL;
  1545.     }
  1546.  
  1547.     /*
  1548.      * Determine where the command should reside. If its name contains 
  1549.      * namespace qualifiers, we put it in the specified namespace; 
  1550.      * otherwise, we always put it in the global namespace.
  1551.      */
  1552.  
  1553.     if (strstr(cmdName, "::") != NULL) {
  1554.     result = TclGetNamespaceForQualName(interp, cmdName, 
  1555.                 (Namespace *) NULL, CREATE_NS_IF_UNKNOWN, &nsPtr, 
  1556.                 &dummy1, &dummy2, &tail);
  1557.     if ((result != TCL_OK) || (nsPtr == NULL) || (tail == NULL)) {
  1558.         return (Tcl_Command) NULL;
  1559.     }
  1560.     } else {
  1561.     nsPtr = iPtr->globalNsPtr;
  1562.     tail = cmdName;
  1563.     }
  1564.  
  1565.     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1566.     if (!new) {
  1567.     cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  1568.  
  1569.     /*
  1570.      * Command already exists. If its object-based Tcl_ObjCmdProc is
  1571.      * TclInvokeStringCommand, we just set its Tcl_ObjCmdProc to the
  1572.      * argument "proc". Otherwise, we delete the old command. 
  1573.      */
  1574.  
  1575.     if (cmdPtr->objProc == TclInvokeStringCommand) {
  1576.         cmdPtr->objProc = proc;
  1577.         cmdPtr->objClientData = clientData;
  1578.             cmdPtr->deleteProc = deleteProc;
  1579.             cmdPtr->deleteData = clientData;
  1580.         return (Tcl_Command) cmdPtr;
  1581.     }
  1582.  
  1583.     Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
  1584.     hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
  1585.     if (!new) {
  1586.         /*
  1587.          * If the deletion callback recreated the command, just throw
  1588.          * away the new command (if we try to delete it again, we
  1589.          * could get stuck in an infinite loop).
  1590.          */
  1591.  
  1592.          ckfree((char *) Tcl_GetHashValue(hPtr));
  1593.     }
  1594.     }
  1595.     cmdPtr = (Command *) ckalloc(sizeof(Command));
  1596.     Tcl_SetHashValue(hPtr, cmdPtr);
  1597.     cmdPtr->hPtr = hPtr;
  1598.     cmdPtr->nsPtr = nsPtr;
  1599.     cmdPtr->refCount = 1;
  1600.     cmdPtr->cmdEpoch = 0;
  1601.     cmdPtr->compileProc = (CompileProc *) NULL;
  1602.     cmdPtr->objProc = proc;
  1603.     cmdPtr->objClientData = clientData;
  1604.     cmdPtr->proc = TclInvokeObjectCommand;
  1605.     cmdPtr->clientData = (ClientData) cmdPtr;
  1606.     cmdPtr->deleteProc = deleteProc;
  1607.     cmdPtr->deleteData = clientData;
  1608.     cmdPtr->deleted = 0;
  1609.     cmdPtr->importRefPtr = NULL;
  1610.     
  1611.     return (Tcl_Command) cmdPtr;
  1612. }
  1613.  
  1614. /*
  1615.  *----------------------------------------------------------------------
  1616.  *
  1617.  * TclInvokeStringCommand --
  1618.  *
  1619.  *    "Wrapper" Tcl_ObjCmdProc used to call an existing string-based
  1620.  *    Tcl_CmdProc if no object-based procedure exists for a command. A
  1621.  *    pointer to this procedure is stored as the Tcl_ObjCmdProc in a
  1622.  *    Command structure. It simply turns around and calls the string
  1623.  *    Tcl_CmdProc in the Command structure.
  1624.  *
  1625.  * Results:
  1626.  *    A standard Tcl object result value.
  1627.  *
  1628.  * Side effects:
  1629.  *    Besides those side effects of the called Tcl_CmdProc,
  1630.  *    TclInvokeStringCommand allocates and frees storage.
  1631.  *
  1632.  *----------------------------------------------------------------------
  1633.  */
  1634.  
  1635. int
  1636. TclInvokeStringCommand(clientData, interp, objc, objv)
  1637.     ClientData clientData;    /* Points to command's Command structure. */
  1638.     Tcl_Interp *interp;        /* Current interpreter. */
  1639.     register int objc;        /* Number of arguments. */
  1640.     Tcl_Obj *CONST objv[];    /* Argument objects. */
  1641. {
  1642.     register Command *cmdPtr = (Command *) clientData;
  1643.     register int i;
  1644.     int result;
  1645.  
  1646.     /*
  1647.      * This procedure generates an argv array for the string arguments. It
  1648.      * starts out with stack-allocated space but uses dynamically-allocated
  1649.      * storage if needed.
  1650.      */
  1651.  
  1652. #define NUM_ARGS 20
  1653.     char *(argStorage[NUM_ARGS]);
  1654.     char **argv = argStorage;
  1655.  
  1656.     /*
  1657.      * Create the string argument array "argv". Make sure argv is large
  1658.      * enough to hold the objc arguments plus 1 extra for the zero
  1659.      * end-of-argv word.
  1660.      * THIS FAILS IF ANY ARGUMENT OBJECT CONTAINS AN EMBEDDED NULL.
  1661.      */
  1662.  
  1663.     if ((objc + 1) > NUM_ARGS) {
  1664.     argv = (char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
  1665.     }
  1666.  
  1667.     for (i = 0;  i < objc;  i++) {
  1668.     argv[i] = Tcl_GetStringFromObj(objv[i], (int *) NULL);
  1669.     }
  1670.     argv[objc] = 0;
  1671.  
  1672.     /*
  1673.      * Invoke the command's string-based Tcl_CmdProc.
  1674.      */
  1675.  
  1676.     result = (*cmdPtr->proc)(cmdPtr->clientData, interp, objc, argv);
  1677.  
  1678.     /*
  1679.      * Free the argv array if malloc'ed storage was used.
  1680.      */
  1681.  
  1682.     if (argv != argStorage) {
  1683.     ckfree((char *) argv);
  1684.     }
  1685.     return result;
  1686. #undef NUM_ARGS
  1687. }
  1688.  
  1689. /*
  1690.  *----------------------------------------------------------------------
  1691.  *
  1692.  * TclInvokeObjectCommand --
  1693.  *
  1694.  *    "Wrapper" Tcl_CmdProc used to call an existing object-based
  1695.  *    Tcl_ObjCmdProc if no string-based procedure exists for a command.
  1696.  *    A pointer to this procedure is stored as the Tcl_CmdProc in a
  1697.  *    Command structure. It simply turns around and calls the object
  1698.  *    Tcl_ObjCmdProc in the Command structure.
  1699.  *
  1700.  * Results:
  1701.  *    A standard Tcl string result value.
  1702.  *
  1703.  * Side effects:
  1704.  *    Besides those side effects of the called Tcl_CmdProc,
  1705.  *    TclInvokeStringCommand allocates and frees storage.
  1706.  *
  1707.  *----------------------------------------------------------------------
  1708.  */
  1709.  
  1710. int
  1711. TclInvokeObjectCommand(clientData, interp, argc, argv)
  1712.     ClientData clientData;    /* Points to command's Command structure. */
  1713.     Tcl_Interp *interp;        /* Current interpreter. */
  1714.     int argc;            /* Number of arguments. */
  1715.     register char **argv;    /* Argument strings. */
  1716. {
  1717.     Command *cmdPtr = (Command *) clientData;
  1718.     register Tcl_Obj *objPtr;
  1719.     register int i;
  1720.     int length, result;
  1721.  
  1722.     /*
  1723.      * This procedure generates an objv array for object arguments that hold
  1724.      * the argv strings. It starts out with stack-allocated space but uses
  1725.      * dynamically-allocated storage if needed.
  1726.      */
  1727.  
  1728. #define NUM_ARGS 20
  1729.     Tcl_Obj *(argStorage[NUM_ARGS]);
  1730.     register Tcl_Obj **objv = argStorage;
  1731.  
  1732.     /*
  1733.      * Create the object argument array "objv". Make sure objv is large
  1734.      * enough to hold the objc arguments plus 1 extra for the zero
  1735.      * end-of-objv word.
  1736.      */
  1737.  
  1738.     if ((argc + 1) > NUM_ARGS) {
  1739.     objv = (Tcl_Obj **)
  1740.         ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
  1741.     }
  1742.  
  1743.     for (i = 0;  i < argc;  i++) {
  1744.     length = strlen(argv[i]);
  1745.     TclNewObj(objPtr);
  1746.     TclInitStringRep(objPtr, argv[i], length);
  1747.     Tcl_IncrRefCount(objPtr);
  1748.     objv[i] = objPtr;
  1749.     }
  1750.     objv[argc] = 0;
  1751.  
  1752.     /*
  1753.      * Invoke the command's object-based Tcl_ObjCmdProc.
  1754.      */
  1755.  
  1756.     result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);
  1757.  
  1758.     /*
  1759.      * Move the interpreter's object result to the string result, 
  1760.      * then reset the object result.
  1761.      * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULL BYTES.
  1762.      */
  1763.  
  1764.     Tcl_SetResult(interp,
  1765.         TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
  1766.         TCL_VOLATILE);
  1767.     
  1768.     /*
  1769.      * Decrement the ref counts for the argument objects created above,
  1770.      * then free the objv array if malloc'ed storage was used.
  1771.      */
  1772.  
  1773.     for (i = 0;  i < argc;  i++) {
  1774.     objPtr = objv[i];
  1775.     Tcl_DecrRefCount(objPtr);
  1776.     }
  1777.     if (objv != argStorage) {
  1778.     ckfree((char *) objv);
  1779.     }
  1780.     return result;
  1781. #undef NUM_ARGS
  1782. }
  1783.  
  1784. /*
  1785.  *----------------------------------------------------------------------
  1786.  *
  1787.  * TclRenameCommand --
  1788.  *
  1789.  *      Called to give an existing Tcl command a different name. Both the
  1790.  *      old command name and the new command name can have "::" namespace
  1791.  *      qualifiers. If the new command has a different namespace context,
  1792.  *      the command will be moved to that namespace and will execute in
  1793.  *    the context of that new namespace.
  1794.  *
  1795.  *      If the new command name is NULL or the null string, the command is
  1796.  *      deleted.
  1797.  *
  1798.  * Results:
  1799.  *      Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
  1800.  *
  1801.  * Side effects:
  1802.  *      If anything goes wrong, an error message is returned in the
  1803.  *      interpreter's result object.
  1804.  *
  1805.  *----------------------------------------------------------------------
  1806.  */
  1807.  
  1808. int
  1809. TclRenameCommand(interp, oldName, newName)
  1810.     Tcl_Interp *interp;                 /* Current interpreter. */
  1811.     char *oldName;                      /* Existing command name. */
  1812.     char *newName;                      /* New command name. */
  1813. {
  1814.     Interp *iPtr = (Interp *) interp;
  1815.     char *newTail;
  1816.     Namespace *cmdNsPtr, *newNsPtr, *dummy1, *dummy2;
  1817.     Tcl_Command cmd;
  1818.     Command *cmdPtr;
  1819.     Tcl_HashEntry *hPtr, *oldHPtr;
  1820.     int new, result;
  1821.  
  1822.     /*
  1823.      * Find the existing command. An error is returned if cmdName can't
  1824.      * be found.
  1825.      */
  1826.  
  1827.     cmd = Tcl_FindCommand(interp, oldName, (Tcl_Namespace *) NULL,
  1828.     /*flags*/ 0);
  1829.     cmdPtr = (Command *) cmd;
  1830.     if (cmdPtr == NULL) {
  1831.     Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't ",
  1832.                 ((newName == NULL)||(*newName == '\0'))? "delete":"rename",
  1833.                 " \"", oldName, "\": command doesn't exist", (char *) NULL);
  1834.     return TCL_ERROR;
  1835.     }
  1836.     cmdNsPtr = cmdPtr->nsPtr;
  1837.  
  1838.     /*
  1839.      * If the new command name is NULL or empty, delete the command. Do this
  1840.      * with Tcl_DeleteCommandFromToken, since we already have the command.
  1841.      */
  1842.     
  1843.     if ((newName == NULL) || (*newName == '\0')) {
  1844.     Tcl_DeleteCommandFromToken(interp, cmd);
  1845.     return TCL_OK;
  1846.     }
  1847.  
  1848.     /*
  1849.      * Make sure that the destination command does not already exist.
  1850.      * The rename operation is like creating a command, so we should
  1851.      * automatically create the containing namespaces just like
  1852.      * Tcl_CreateCommand would.
  1853.      */
  1854.  
  1855.     result = TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,
  1856.             (CREATE_NS_IF_UNKNOWN | TCL_LEAVE_ERR_MSG),
  1857.             &newNsPtr, &dummy1, &dummy2, &newTail);
  1858.     if (result != TCL_OK) {
  1859.         return result;
  1860.     }
  1861.     if ((newNsPtr == NULL) || (newTail == NULL)) {
  1862.     Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1863.          "can't rename to \"", newName, "\": bad command name",
  1864.                  (char *) NULL);
  1865.         return TCL_ERROR;
  1866.     }
  1867.     if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
  1868.     Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  1869.          "can't rename to \"", newName,
  1870.          "\": command already exists", (char *) NULL);
  1871.         return TCL_ERROR;
  1872.     }
  1873.  
  1874.  
  1875.     /*
  1876.      * Warning: any changes done in the code here are likely
  1877.      * to be needed in Tcl_HideCommand() code too.
  1878.      * (until the common parts are extracted out)     --dl
  1879.      */
  1880.  
  1881.     /*
  1882.      * Put the command in the new namespace so we can check for an alias
  1883.      * loop. Since we are adding a new command to a namespace, we must
  1884.      * handle any shadowing of the global commands that this might create.
  1885.      */
  1886.     
  1887.     oldHPtr = cmdPtr->hPtr;
  1888.     hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &new);
  1889.     Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
  1890.     cmdPtr->hPtr = hPtr;
  1891.     cmdPtr->nsPtr = newNsPtr;
  1892.     TclResetShadowedCmdRefs(interp, cmdPtr);
  1893.  
  1894.     /*
  1895.      * Now check for an alias loop. If we detect one, put everything back
  1896.      * the way it was and report the error.
  1897.      */
  1898.  
  1899.     result = TclPreventAliasLoop(interp, interp, (Tcl_Command) cmdPtr);
  1900.     if (result != TCL_OK) {
  1901.         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  1902.         cmdPtr->hPtr = oldHPtr;
  1903.         cmdPtr->nsPtr = cmdNsPtr;
  1904.         return result;
  1905.     }
  1906.  
  1907.     /*
  1908.      * The new command name is okay, so remove the command from its
  1909.      * current namespace. This is like deleting the command, so bump
  1910.      * the cmdEpoch to invalidate any cached references to the command.
  1911.      */
  1912.     
  1913.     Tcl_DeleteHashEntry(oldHPtr);
  1914.     cmdPtr->cmdEpoch++;
  1915.  
  1916.     /*
  1917.      * If the command being renamed has a compile procedure, increment the
  1918.      * interpreter's compileEpoch to invalidate its compiled code. This
  1919.      * makes sure that we don't later try to execute old code compiled for
  1920.      * the now-renamed command.
  1921.      */
  1922.  
  1923.     if (cmdPtr->compileProc != NULL) {
  1924.     iPtr->compileEpoch++;
  1925.     }
  1926.  
  1927.     return TCL_OK;
  1928. }
  1929.  
  1930. /*
  1931.  *----------------------------------------------------------------------
  1932.  *
  1933.  * Tcl_SetCommandInfo --
  1934.  *
  1935.  *    Modifies various information about a Tcl command. Note that
  1936.  *    this procedure will not change a command's namespace; use
  1937.  *    Tcl_RenameCommand to do that. Also, the isNativeObjectProc
  1938.  *    member of *infoPtr is ignored.
  1939.  *
  1940.  * Results:
  1941.  *    If cmdName exists in interp, then the information at *infoPtr
  1942.  *    is stored with the command in place of the current information
  1943.  *    and 1 is returned. If the command doesn't exist then 0 is
  1944.  *    returned. 
  1945.  *
  1946.  * Side effects:
  1947.  *    None.
  1948.  *
  1949.  *----------------------------------------------------------------------
  1950.  */
  1951.  
  1952. int
  1953. Tcl_SetCommandInfo(interp, cmdName, infoPtr)
  1954.     Tcl_Interp *interp;            /* Interpreter in which to look
  1955.                      * for command. */
  1956.     char *cmdName;            /* Name of desired command. */
  1957.     Tcl_CmdInfo *infoPtr;        /* Where to store information about
  1958.                      * command. */
  1959. {
  1960.     Tcl_Command cmd;
  1961.     Command *cmdPtr;
  1962.  
  1963.     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  1964.             /*flags*/ 0);
  1965.     if (cmd == (Tcl_Command) NULL) {
  1966.     return 0;
  1967.     }
  1968.  
  1969.     /*
  1970.      * The isNativeObjectProc and nsPtr members of *infoPtr are ignored.
  1971.      */
  1972.     
  1973.     cmdPtr = (Command *) cmd;
  1974.     cmdPtr->proc = infoPtr->proc;
  1975.     cmdPtr->clientData = infoPtr->clientData;
  1976.     if (infoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
  1977.     cmdPtr->objProc = TclInvokeStringCommand;
  1978.     cmdPtr->objClientData = (ClientData) cmdPtr;
  1979.     } else {
  1980.     cmdPtr->objProc = infoPtr->objProc;
  1981.     cmdPtr->objClientData = infoPtr->objClientData;
  1982.     }
  1983.     cmdPtr->deleteProc = infoPtr->deleteProc;
  1984.     cmdPtr->deleteData = infoPtr->deleteData;
  1985.     return 1;
  1986. }
  1987.  
  1988. /*
  1989.  *----------------------------------------------------------------------
  1990.  *
  1991.  * Tcl_GetCommandInfo --
  1992.  *
  1993.  *    Returns various information about a Tcl command.
  1994.  *
  1995.  * Results:
  1996.  *    If cmdName exists in interp, then *infoPtr is modified to
  1997.  *    hold information about cmdName and 1 is returned.  If the
  1998.  *    command doesn't exist then 0 is returned and *infoPtr isn't
  1999.  *    modified.
  2000.  *
  2001.  * Side effects:
  2002.  *    None.
  2003.  *
  2004.  *----------------------------------------------------------------------
  2005.  */
  2006.  
  2007. int
  2008. Tcl_GetCommandInfo(interp, cmdName, infoPtr)
  2009.     Tcl_Interp *interp;            /* Interpreter in which to look
  2010.                      * for command. */
  2011.     char *cmdName;            /* Name of desired command. */
  2012.     Tcl_CmdInfo *infoPtr;        /* Where to store information about
  2013.                      * command. */
  2014. {
  2015.     Tcl_Command cmd;
  2016.     Command *cmdPtr;
  2017.  
  2018.     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  2019.             /*flags*/ 0);
  2020.     if (cmd == (Tcl_Command) NULL) {
  2021.     return 0;
  2022.     }
  2023.  
  2024.     /*
  2025.      * Set isNativeObjectProc 1 if objProc was registered by a call to
  2026.      * Tcl_CreateObjCommand. Otherwise set it to 0.
  2027.      */
  2028.  
  2029.     cmdPtr = (Command *) cmd;
  2030.     infoPtr->isNativeObjectProc =
  2031.         (cmdPtr->objProc != TclInvokeStringCommand);
  2032.     infoPtr->objProc = cmdPtr->objProc;
  2033.     infoPtr->objClientData = cmdPtr->objClientData;
  2034.     infoPtr->proc = cmdPtr->proc;
  2035.     infoPtr->clientData = cmdPtr->clientData;
  2036.     infoPtr->deleteProc = cmdPtr->deleteProc;
  2037.     infoPtr->deleteData = cmdPtr->deleteData;
  2038.     infoPtr->namespacePtr = (Tcl_Namespace *) cmdPtr->nsPtr;
  2039.     return 1;
  2040. }
  2041.  
  2042. /*
  2043.  *----------------------------------------------------------------------
  2044.  *
  2045.  * Tcl_GetCommandName --
  2046.  *
  2047.  *    Given a token returned by Tcl_CreateCommand, this procedure
  2048.  *    returns the current name of the command (which may have changed
  2049.  *    due to renaming).
  2050.  *
  2051.  * Results:
  2052.  *    The return value is the name of the given command.
  2053.  *
  2054.  * Side effects:
  2055.  *    None.
  2056.  *
  2057.  *----------------------------------------------------------------------
  2058.  */
  2059.  
  2060. char *
  2061. Tcl_GetCommandName(interp, command)
  2062.     Tcl_Interp *interp;        /* Interpreter containing the command. */
  2063.     Tcl_Command command;    /* Token for command returned by a previous
  2064.                  * call to Tcl_CreateCommand. The command
  2065.                  * must not have been deleted. */
  2066. {
  2067.     Command *cmdPtr = (Command *) command;
  2068.  
  2069.     if ((cmdPtr == NULL) || (cmdPtr->hPtr == NULL)) {
  2070.  
  2071.     /*
  2072.      * This should only happen if command was "created" after the
  2073.      * interpreter began to be deleted, so there isn't really any
  2074.      * command. Just return an empty string.
  2075.      */
  2076.  
  2077.     return "";
  2078.     }
  2079.     return Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
  2080. }
  2081.  
  2082. /*
  2083.  *----------------------------------------------------------------------
  2084.  *
  2085.  * Tcl_GetCommandFullName --
  2086.  *
  2087.  *    Given a token returned by, e.g., Tcl_CreateCommand or
  2088.  *    Tcl_FindCommand, this procedure appends to an object the command's
  2089.  *    full name, qualified by a sequence of parent namespace names. The
  2090.  *    command's fully-qualified name may have changed due to renaming.
  2091.  *
  2092.  * Results:
  2093.  *    None.
  2094.  *
  2095.  * Side effects:
  2096.  *    The command's fully-qualified name is appended to the string
  2097.  *    representation of objPtr. 
  2098.  *
  2099.  *----------------------------------------------------------------------
  2100.  */
  2101.  
  2102. void
  2103. Tcl_GetCommandFullName(interp, command, objPtr)
  2104.     Tcl_Interp *interp;        /* Interpreter containing the command. */
  2105.     Tcl_Command command;    /* Token for command returned by a previous
  2106.                  * call to Tcl_CreateCommand. The command
  2107.                  * must not have been deleted. */
  2108.     Tcl_Obj *objPtr;        /* Points to the object onto which the
  2109.                  * command's full name is appended. */
  2110.  
  2111. {
  2112.     Interp *iPtr = (Interp *) interp;
  2113.     register Command *cmdPtr = (Command *) command;
  2114.     char *name;
  2115.  
  2116.     /*
  2117.      * Add the full name of the containing namespace, followed by the "::"
  2118.      * separator, and the command name.
  2119.      */
  2120.  
  2121.     if (cmdPtr != NULL) {
  2122.     if (cmdPtr->nsPtr != NULL) {
  2123.         Tcl_AppendToObj(objPtr, cmdPtr->nsPtr->fullName, -1);
  2124.         if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
  2125.         Tcl_AppendToObj(objPtr, "::", 2);
  2126.         }
  2127.     }
  2128.     if (cmdPtr->hPtr != NULL) {
  2129.         name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
  2130.         Tcl_AppendToObj(objPtr, name, -1);
  2131.     }
  2132.     }
  2133. }
  2134.  
  2135. /*
  2136.  *----------------------------------------------------------------------
  2137.  *
  2138.  * Tcl_DeleteCommand --
  2139.  *
  2140.  *    Remove the given command from the given interpreter.
  2141.  *
  2142.  * Results:
  2143.  *    0 is returned if the command was deleted successfully.
  2144.  *    -1 is returned if there didn't exist a command by that name.
  2145.  *
  2146.  * Side effects:
  2147.  *    cmdName will no longer be recognized as a valid command for
  2148.  *    interp.
  2149.  *
  2150.  *----------------------------------------------------------------------
  2151.  */
  2152.  
  2153. int
  2154. Tcl_DeleteCommand(interp, cmdName)
  2155.     Tcl_Interp *interp;        /* Token for command interpreter (returned
  2156.                  * by a previous Tcl_CreateInterp call). */
  2157.     char *cmdName;        /* Name of command to remove. */
  2158. {
  2159.     Tcl_Command cmd;
  2160.  
  2161.     /*
  2162.      *  Find the desired command and delete it.
  2163.      */
  2164.  
  2165.     cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
  2166.             /*flags*/ 0);
  2167.     if (cmd == (Tcl_Command) NULL) {
  2168.     return -1;
  2169.     }
  2170.     return Tcl_DeleteCommandFromToken(interp, cmd);
  2171. }
  2172.  
  2173. /*
  2174.  *----------------------------------------------------------------------
  2175.  *
  2176.  * Tcl_DeleteCommandFromToken --
  2177.  *
  2178.  *    Removes the given command from the given interpreter. This procedure
  2179.  *    resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead
  2180.  *    of a command name for efficiency.
  2181.  *
  2182.  * Results:
  2183.  *    0 is returned if the command was deleted successfully.
  2184.  *    -1 is returned if there didn't exist a command by that name.
  2185.  *
  2186.  * Side effects:
  2187.  *    The command specified by "cmd" will no longer be recognized as a
  2188.  *    valid command for "interp".
  2189.  *
  2190.  *----------------------------------------------------------------------
  2191.  */
  2192.  
  2193. int
  2194. Tcl_DeleteCommandFromToken(interp, cmd)
  2195.     Tcl_Interp *interp;        /* Token for command interpreter returned by
  2196.                  * a previous call to Tcl_CreateInterp. */
  2197.     Tcl_Command cmd;            /* Token for command to delete. */
  2198. {
  2199.     Interp *iPtr = (Interp *) interp;
  2200.     Command *cmdPtr = (Command *) cmd;
  2201.     ImportRef *refPtr, *nextRefPtr;
  2202.     Tcl_Command importCmd;
  2203.  
  2204.     /*
  2205.      * The code here is tricky.  We can't delete the hash table entry
  2206.      * before invoking the deletion callback because there are cases
  2207.      * where the deletion callback needs to invoke the command (e.g.
  2208.      * object systems such as OTcl). However, this means that the
  2209.      * callback could try to delete or rename the command. The deleted
  2210.      * flag allows us to detect these cases and skip nested deletes.
  2211.      */
  2212.  
  2213.     if (cmdPtr->deleted) {
  2214.     /*
  2215.      * Another deletion is already in progress.  Remove the hash
  2216.      * table entry now, but don't invoke a callback or free the
  2217.      * command structure.
  2218.      */
  2219.  
  2220.         Tcl_DeleteHashEntry(cmdPtr->hPtr);
  2221.     cmdPtr->hPtr = NULL;
  2222.     return 0;
  2223.     }
  2224.  
  2225.     /*
  2226.      * If the command being deleted has a compile procedure, increment the
  2227.      * interpreter's compileEpoch to invalidate its compiled code. This
  2228.      * makes sure that we don't later try to execute old code compiled with
  2229.      * command-specific (i.e., inline) bytecodes for the now-deleted
  2230.      * command. This field is checked in Tcl_EvalObj and ObjInterpProc, and
  2231.      * code whose compilation epoch doesn't match is recompiled.
  2232.      */
  2233.  
  2234.     if (cmdPtr->compileProc != NULL) {
  2235.         iPtr->compileEpoch++;
  2236.     }
  2237.  
  2238.     cmdPtr->deleted = 1;
  2239.     if (cmdPtr->deleteProc != NULL) {
  2240.     /*
  2241.      * Delete the command's client data. If this was an imported command
  2242.      * created when a command was imported into a namespace, this client
  2243.      * data will be a pointer to a ImportedCmdData structure describing
  2244.      * the "real" command that this imported command refers to.
  2245.      */
  2246.     
  2247.     (*cmdPtr->deleteProc)(cmdPtr->deleteData);
  2248.     }
  2249.  
  2250.     /*
  2251.      * Bump the command epoch counter. This will invalidate all cached
  2252.      * references that point to this command.
  2253.      */
  2254.     
  2255.     cmdPtr->cmdEpoch++;
  2256.  
  2257.     /*
  2258.      * If this command was imported into other namespaces, then imported
  2259.      * commands were created that refer back to this command. Delete these
  2260.      * imported commands now.
  2261.      */
  2262.  
  2263.     for (refPtr = cmdPtr->importRefPtr;  refPtr != NULL;
  2264.             refPtr = nextRefPtr) {
  2265.     nextRefPtr = refPtr->nextPtr;
  2266.     importCmd = (Tcl_Command) refPtr->importedCmdPtr;
  2267.         Tcl_DeleteCommandFromToken(interp, importCmd);
  2268.     }
  2269.  
  2270.     /*
  2271.      * Don't use hPtr to delete the hash entry here, because it's
  2272.      * possible that the deletion callback renamed the command.
  2273.      * Instead, use cmdPtr->hptr, and make sure that no-one else
  2274.      * has already deleted the hash entry.
  2275.      */
  2276.  
  2277.     if (cmdPtr->hPtr != NULL) {
  2278.     Tcl_DeleteHashEntry(cmdPtr->hPtr);
  2279.     }
  2280.  
  2281.     /*
  2282.      * Mark the Command structure as no longer valid. This allows
  2283.      * TclExecuteByteCode to recognize when a Command has logically been
  2284.      * deleted and a pointer to this Command structure cached in a CmdName
  2285.      * object is invalid. TclExecuteByteCode will look up the command again
  2286.      * in the interpreter's command hashtable.
  2287.      */
  2288.  
  2289.     cmdPtr->objProc = NULL;
  2290.  
  2291.     /*
  2292.      * Now free the Command structure, unless there is another reference to
  2293.      * it from a CmdName Tcl object in some ByteCode code sequence. In that
  2294.      * case, delay the cleanup until all references are either discarded
  2295.      * (when a ByteCode is freed) or replaced by a new reference (when a
  2296.      * cached CmdName Command reference is found to be invalid and
  2297.      * TclExecuteByteCode looks up the command in the command hashtable).
  2298.      */
  2299.     
  2300.     TclCleanupCommand(cmdPtr);
  2301.     return 0;
  2302. }
  2303.  
  2304. /*
  2305.  *----------------------------------------------------------------------
  2306.  *
  2307.  * TclCleanupCommand --
  2308.  *
  2309.  *    This procedure frees up a Command structure unless it is still
  2310.  *    referenced from an interpreter's command hashtable or from a CmdName
  2311.  *    Tcl object representing the name of a command in a ByteCode
  2312.  *    instruction sequence. 
  2313.  *
  2314.  * Results:
  2315.  *    None.
  2316.  *
  2317.  * Side effects:
  2318.  *    Memory gets freed unless a reference to the Command structure still
  2319.  *    exists. In that case the cleanup is delayed until the command is
  2320.  *    deleted or when the last ByteCode referring to it is freed.
  2321.  *
  2322.  *----------------------------------------------------------------------
  2323.  */
  2324.  
  2325. void
  2326. TclCleanupCommand(cmdPtr)
  2327.     register Command *cmdPtr;    /* Points to the Command structure to
  2328.                  * be freed. */
  2329. {
  2330.     cmdPtr->refCount--;
  2331.     if (cmdPtr->refCount <= 0) {
  2332.     ckfree((char *) cmdPtr);
  2333.     }
  2334. }
  2335.  
  2336. /*
  2337.  *----------------------------------------------------------------------
  2338.  *
  2339.  * Tcl_Eval --
  2340.  *
  2341.  *    Execute a Tcl command in a string.
  2342.  *
  2343.  * Results:
  2344.  *    The return value is one of the return codes defined in tcl.h
  2345.  *    (such as TCL_OK), and interp->result contains a string value
  2346.  *    to supplement the return code. The value of interp->result
  2347.  *    will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
  2348.  *    you must copy it or lose it!
  2349.  *
  2350.  * Side effects:
  2351.  *    The string is compiled to produce a ByteCode object that holds the
  2352.  *    command's bytecode instructions. However, this ByteCode object is
  2353.  *    lost after executing the command. The command's execution will
  2354.  *    almost certainly have side effects. interp->termOffset is set to the
  2355.  *    offset of the character in "string" just after the last one
  2356.  *    successfully compiled or executed.
  2357.  *
  2358.  *----------------------------------------------------------------------
  2359.  */
  2360.  
  2361. int
  2362. Tcl_Eval(interp, string)
  2363.     Tcl_Interp *interp;        /* Token for command interpreter (returned
  2364.                  * by previous call to Tcl_CreateInterp). */
  2365.     char *string;        /* Pointer to TCL command to execute. */
  2366. {
  2367.     register Tcl_Obj *cmdPtr;
  2368.     int length = strlen(string);
  2369.     int result;
  2370.  
  2371.     if (length > 0) {
  2372.     /*
  2373.      * Initialize a Tcl object from the command string.
  2374.      */
  2375.  
  2376.     TclNewObj(cmdPtr);
  2377.     TclInitStringRep(cmdPtr, string, length);
  2378.     Tcl_IncrRefCount(cmdPtr);
  2379.  
  2380.     /*
  2381.      * Compile and execute the bytecodes.
  2382.      */
  2383.     
  2384.     result = Tcl_EvalObj(interp, cmdPtr);
  2385.  
  2386.     /*
  2387.      * Move the interpreter's object result to the string result, 
  2388.      * then reset the object result.
  2389.      * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
  2390.      */
  2391.  
  2392.     Tcl_SetResult(interp,
  2393.             TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
  2394.             TCL_VOLATILE);
  2395.  
  2396.     /*
  2397.      * Discard the Tcl object created to hold the command and its code.
  2398.      */
  2399.     
  2400.     Tcl_DecrRefCount(cmdPtr);    
  2401.     } else {
  2402.     /*
  2403.      * An empty string. Just reset the interpreter's result.
  2404.      */
  2405.  
  2406.     Tcl_ResetResult(interp);
  2407.     result = TCL_OK;
  2408.     }
  2409.     return result;
  2410. }
  2411.  
  2412. /*
  2413.  *----------------------------------------------------------------------
  2414.  *
  2415.  * Tcl_EvalObj --
  2416.  *
  2417.  *    Execute Tcl commands stored in a Tcl object. These commands are
  2418.  *    compiled into bytecodes if necessary.
  2419.  *
  2420.  * Results:
  2421.  *    The return value is one of the return codes defined in tcl.h
  2422.  *    (such as TCL_OK), and the interpreter's result contains a value
  2423.  *    to supplement the return code.
  2424.  *
  2425.  * Side effects:
  2426.  *    The object is converted, if necessary, to a ByteCode object that
  2427.  *    holds the bytecode instructions for the commands. Executing the
  2428.  *    commands will almost certainly have side effects that depend
  2429.  *    on those commands.
  2430.  *
  2431.  *    Just as in Tcl_Eval, interp->termOffset is set to the offset of the
  2432.  *    last character executed in the objPtr's string.
  2433.  *
  2434.  *----------------------------------------------------------------------
  2435.  */
  2436.  
  2437. int
  2438. Tcl_EvalObj(interp, objPtr)
  2439.     Tcl_Interp *interp;            /* Token for command interpreter
  2440.                      * (returned by a previous call to
  2441.                      * Tcl_CreateInterp). */
  2442.     Tcl_Obj *objPtr;            /* Pointer to object containing
  2443.                      * commands to execute. */
  2444. {
  2445.     register Interp *iPtr = (Interp *) interp;
  2446.     int flags;                /* Interp->evalFlags value when the
  2447.                      * procedure was called. */
  2448.     register ByteCode* codePtr;        /* Tcl Internal type of bytecode. */
  2449.     int oldCount = iPtr->cmdCount;    /* Used to tell whether any commands
  2450.                      * at all were executed. */
  2451.     int numSrcChars;
  2452.     register int result;
  2453.  
  2454.     /*
  2455.      * Reset both the interpreter's string and object results and clear out
  2456.      * any error information. This makes sure that we return an empty
  2457.      * result if there are no commands in the command string.
  2458.      */
  2459.  
  2460.     Tcl_ResetResult(interp);
  2461.  
  2462.     /*
  2463.      * Check depth of nested calls to Tcl_Eval:  if this gets too large,
  2464.      * it's probably because of an infinite loop somewhere.
  2465.      */
  2466.  
  2467.     iPtr->numLevels++;
  2468.     if (iPtr->numLevels > iPtr->maxNestingDepth) {
  2469.     iPtr->numLevels--;
  2470.     Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2471.         "too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
  2472.     return TCL_ERROR;
  2473.     }
  2474.  
  2475.     /*
  2476.      * On the Mac, we will never reach the default recursion limit before blowing
  2477.      * the stack. So we need to do a check here.
  2478.      */
  2479.     
  2480.     if (TclpCheckStackSpace() == 0) {
  2481.     /*NOTREACHED*/
  2482.         iPtr->numLevels--;
  2483.         Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2484.             "too many nested calls to Tcl_EvalObj (infinite loop?)", -1);
  2485.         return TCL_ERROR;
  2486.     }
  2487.  
  2488.     /*
  2489.      * If the interpreter has been deleted, return an error.
  2490.      */
  2491.     
  2492.     if (iPtr->flags & DELETED) {
  2493.     Tcl_ResetResult(interp);
  2494.     Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2495.             "attempt to call eval in deleted interpreter", -1);
  2496.     Tcl_SetErrorCode(interp, "CORE", "IDELETE",
  2497.             "attempt to call eval in deleted interpreter", (char *) NULL);
  2498.     iPtr->numLevels--;
  2499.     return TCL_ERROR;
  2500.     }
  2501.  
  2502.     /*
  2503.      * Get the ByteCode from the object. If it exists, make sure it hasn't
  2504.      * been invalidated by, e.g., someone redefining a command with a
  2505.      * compile procedure (this might make the compiled code wrong). If
  2506.      * necessary, convert the object to be a ByteCode object and compile it.
  2507.      * Also, if the code was compiled in/for a different interpreter,
  2508.      * we recompile it.
  2509.      */
  2510.  
  2511.     if (objPtr->typePtr == &tclByteCodeType) {
  2512.     codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
  2513.     
  2514.     if ((codePtr->iPtr != iPtr)
  2515.             || (codePtr->compileEpoch != iPtr->compileEpoch)) {
  2516.         tclByteCodeType.freeIntRepProc(objPtr);
  2517.     }
  2518.     }
  2519.     if (objPtr->typePtr != &tclByteCodeType) {
  2520.     /*
  2521.      * First reset any error line number information.
  2522.      */
  2523.     
  2524.     iPtr->errorLine = 1;   /* no correct line # information yet */
  2525.     result = tclByteCodeType.setFromAnyProc(interp, objPtr);
  2526.     if (result != TCL_OK) {
  2527.         iPtr->numLevels--;
  2528.         return result;
  2529.     }
  2530.     }
  2531.     codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
  2532.  
  2533.     /*
  2534.      * Extract then reset the compilation flags in the interpreter.
  2535.      * Resetting the flags must be done after any compilation.
  2536.      */
  2537.  
  2538.     flags = iPtr->evalFlags;
  2539.     iPtr->evalFlags = 0;
  2540.  
  2541.     /*
  2542.      * Execute the commands. If the code was compiled from an empty string,
  2543.      * don't bother executing the code.
  2544.      */
  2545.  
  2546.     numSrcChars = codePtr->numSrcChars;
  2547.     if (numSrcChars > 0) {
  2548.     /*
  2549.      * Increment the code's ref count while it is being executed. If
  2550.      * afterwards no references to it remain, free the code.
  2551.      */
  2552.     
  2553.     codePtr->refCount++;
  2554.     result = TclExecuteByteCode(interp, codePtr);
  2555.     codePtr->refCount--;
  2556.     if (codePtr->refCount <= 0) {
  2557.         TclCleanupByteCode(codePtr);
  2558.     }
  2559.     } else {
  2560.     Tcl_ResetResult(interp);
  2561.     result = TCL_OK;
  2562.     }
  2563.  
  2564.     /*
  2565.      * If no commands at all were executed, check for asynchronous
  2566.      * handlers so that they at least get one change to execute.
  2567.      * This is needed to handle event loops written in Tcl with
  2568.      * empty bodies.
  2569.      */
  2570.  
  2571.     if ((oldCount == iPtr->cmdCount) && (Tcl_AsyncReady())) {
  2572.     result = Tcl_AsyncInvoke(interp, result);
  2573.     }
  2574.  
  2575.     /*
  2576.      * Free up any extra resources that were allocated.
  2577.      */
  2578.  
  2579.     iPtr->numLevels--;
  2580.     if (iPtr->numLevels == 0) {
  2581.     if (result == TCL_RETURN) {
  2582.         result = TclUpdateReturnInfo(iPtr);
  2583.     }
  2584.     if ((result != TCL_OK) && (result != TCL_ERROR)
  2585.         && !(flags & TCL_ALLOW_EXCEPTIONS)) {
  2586.         Tcl_ResetResult(interp);
  2587.         if (result == TCL_BREAK) {
  2588.         Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2589.                 "invoked \"break\" outside of a loop", -1);
  2590.         } else if (result == TCL_CONTINUE) {
  2591.         Tcl_AppendToObj(Tcl_GetObjResult(interp),
  2592.                 "invoked \"continue\" outside of a loop", -1);
  2593.         } else {
  2594.         char buf[50];
  2595.         sprintf(buf, "command returned bad code: %d", result);
  2596.         Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
  2597.         }
  2598.         result = TCL_ERROR;
  2599.     }
  2600.     }
  2601.  
  2602.     /*
  2603.      * If an error occurred, record information about what was being
  2604.      * executed when the error occurred.
  2605.      */
  2606.  
  2607.     if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
  2608.     char buf[200];
  2609.     char *ellipsis = "";
  2610.     char *bytes;
  2611.     int length;
  2612.  
  2613.     /*
  2614.      * Figure out how much of the command to print in the error
  2615.      * message (up to a certain number of characters, or up to
  2616.      * the first new-line).
  2617.      * THIS FAILS IF THE OBJECT'S STRING REP CONTAINS A NULL.
  2618.      */
  2619.  
  2620.     bytes = Tcl_GetStringFromObj(objPtr, &length);
  2621.     length = TclMin(numSrcChars, length);
  2622.     if (length > 150) {
  2623.         length = 150;
  2624.         ellipsis = " ...";
  2625.     }
  2626.  
  2627.     if (!(iPtr->flags & ERR_IN_PROGRESS)) {
  2628.         sprintf(buf, "\n    while executing\n\"%.*s%s\"",
  2629.             length, bytes, ellipsis);
  2630.     } else {
  2631.         sprintf(buf, "\n    invoked from within\n\"%.*s%s\"",
  2632.             length, bytes, ellipsis);
  2633.     }
  2634.     Tcl_AddObjErrorInfo(interp, buf, -1);
  2635.     }
  2636.  
  2637.     /*
  2638.      * Set the interpreter's termOffset member to the offset of the
  2639.      * character just after the last one executed. We approximate the offset
  2640.      * of the last character executed by using the number of characters
  2641.      * compiled.
  2642.      */
  2643.  
  2644.     iPtr->termOffset = numSrcChars;
  2645.     iPtr->flags &= ~ERR_ALREADY_LOGGED;
  2646.     return result;
  2647. }
  2648.  
  2649. /*
  2650.  *--------------------------------------------------------------
  2651.  *
  2652.  * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
  2653.  *
  2654.  *    Procedures to evaluate an expression and return its value in a
  2655.  *    particular form.
  2656.  *
  2657.  * Results:
  2658.  *    Each of the procedures below returns a standard Tcl result. If an
  2659.  *    error occurs then an error message is left in interp->result.
  2660.  *    Otherwise the value of the expression, in the appropriate form, is
  2661.  *    stored at *ptr. If the expression had a result that was
  2662.  *    incompatible with the desired form then an error is returned.
  2663.  *
  2664.  * Side effects:
  2665.  *    None.
  2666.  *
  2667.  *--------------------------------------------------------------
  2668.  */
  2669.  
  2670. int
  2671. Tcl_ExprLong(interp, string, ptr)
  2672.     Tcl_Interp *interp;        /* Context in which to evaluate the
  2673.                  * expression. */
  2674.     char *string;        /* Expression to evaluate. */
  2675.     long *ptr;            /* Where to store result. */
  2676. {
  2677.     register Tcl_Obj *exprPtr;
  2678.     Tcl_Obj *resultPtr;
  2679.     int length = strlen(string);
  2680.     int result = TCL_OK;
  2681.  
  2682.     if (length > 0) {
  2683.     exprPtr = Tcl_NewStringObj(string, length);
  2684.     Tcl_IncrRefCount(exprPtr);
  2685.     result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  2686.     if (result == TCL_OK) {
  2687.         /*
  2688.          * Store an integer based on the expression result.
  2689.          */
  2690.         
  2691.         if (resultPtr->typePtr == &tclIntType) {
  2692.         *ptr = resultPtr->internalRep.longValue;
  2693.         } else if (resultPtr->typePtr == &tclDoubleType) {
  2694.         *ptr = (long) resultPtr->internalRep.doubleValue;
  2695.         } else {
  2696.         Tcl_SetResult(interp,
  2697.                 "expression didn't have numeric value", TCL_STATIC);
  2698.         result = TCL_ERROR;
  2699.         }
  2700.         Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2701.     } else {
  2702.         /*
  2703.          * Move the interpreter's object result to the string result, 
  2704.          * then reset the object result.
  2705.          * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
  2706.          */
  2707.  
  2708.         Tcl_SetResult(interp,
  2709.                 TclGetStringFromObj(Tcl_GetObjResult(interp),
  2710.                     (int *) NULL),
  2711.                 TCL_VOLATILE);
  2712.     }
  2713.     Tcl_DecrRefCount(exprPtr);  /* discard the expression object */    
  2714.     } else {
  2715.     /*
  2716.      * An empty string. Just set the result integer to 0.
  2717.      */
  2718.     
  2719.     *ptr = 0;
  2720.     }
  2721.     return result;
  2722. }
  2723.  
  2724. int
  2725. Tcl_ExprDouble(interp, string, ptr)
  2726.     Tcl_Interp *interp;        /* Context in which to evaluate the
  2727.                  * expression. */
  2728.     char *string;        /* Expression to evaluate. */
  2729.     double *ptr;        /* Where to store result. */
  2730. {
  2731.     register Tcl_Obj *exprPtr;
  2732.     Tcl_Obj *resultPtr;
  2733.     int length = strlen(string);
  2734.     int result = TCL_OK;
  2735.  
  2736.     if (length > 0) {
  2737.     exprPtr = Tcl_NewStringObj(string, length);
  2738.     Tcl_IncrRefCount(exprPtr);
  2739.     result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  2740.     if (result == TCL_OK) {
  2741.         /*
  2742.          * Store a double  based on the expression result.
  2743.          */
  2744.         
  2745.         if (resultPtr->typePtr == &tclIntType) {
  2746.         *ptr = (double) resultPtr->internalRep.longValue;
  2747.         } else if (resultPtr->typePtr == &tclDoubleType) {
  2748.         *ptr = resultPtr->internalRep.doubleValue;
  2749.         } else {
  2750.         Tcl_SetResult(interp,
  2751.                 "expression didn't have numeric value", TCL_STATIC);
  2752.         result = TCL_ERROR;
  2753.         }
  2754.         Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2755.     } else {
  2756.         /*
  2757.          * Move the interpreter's object result to the string result, 
  2758.          * then reset the object result.
  2759.          * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
  2760.          */
  2761.  
  2762.         Tcl_SetResult(interp,
  2763.                 TclGetStringFromObj(Tcl_GetObjResult(interp),
  2764.                     (int *) NULL),
  2765.                 TCL_VOLATILE);
  2766.     }
  2767.     Tcl_DecrRefCount(exprPtr);  /* discard the expression object */
  2768.     } else {
  2769.     /*
  2770.      * An empty string. Just set the result double to 0.0.
  2771.      */
  2772.     
  2773.     *ptr = 0.0;
  2774.     }
  2775.     return result;
  2776. }
  2777.  
  2778. int
  2779. Tcl_ExprBoolean(interp, string, ptr)
  2780.     Tcl_Interp *interp;        /* Context in which to evaluate the
  2781.                      * expression. */
  2782.     char *string;        /* Expression to evaluate. */
  2783.     int *ptr;            /* Where to store 0/1 result. */
  2784. {
  2785.     register Tcl_Obj *exprPtr;
  2786.     Tcl_Obj *resultPtr;
  2787.     int length = strlen(string);
  2788.     int result = TCL_OK;
  2789.  
  2790.     if (length > 0) {
  2791.     exprPtr = Tcl_NewStringObj(string, length);
  2792.     Tcl_IncrRefCount(exprPtr);
  2793.     result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  2794.     if (result == TCL_OK) {
  2795.         /*
  2796.          * Store a boolean based on the expression result.
  2797.          */
  2798.         
  2799.         if (resultPtr->typePtr == &tclIntType) {
  2800.         *ptr = (resultPtr->internalRep.longValue != 0);
  2801.         } else if (resultPtr->typePtr == &tclDoubleType) {
  2802.         *ptr = (resultPtr->internalRep.doubleValue != 0.0);
  2803.         } else {
  2804.         result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
  2805.         }
  2806.         Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2807.     }
  2808.     if (result != TCL_OK) {
  2809.         /*
  2810.          * Move the interpreter's object result to the string result, 
  2811.          * then reset the object result.
  2812.          * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
  2813.          */
  2814.  
  2815.         Tcl_SetResult(interp,
  2816.                 TclGetStringFromObj(Tcl_GetObjResult(interp),
  2817.                     (int *) NULL),
  2818.                 TCL_VOLATILE);
  2819.     }
  2820.     Tcl_DecrRefCount(exprPtr); /* discard the expression object */
  2821.     } else {
  2822.     /*
  2823.      * An empty string. Just set the result boolean to 0 (false).
  2824.      */
  2825.     
  2826.     *ptr = 0;
  2827.     }
  2828.     return result;
  2829. }
  2830.  
  2831. /*
  2832.  *--------------------------------------------------------------
  2833.  *
  2834.  * Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj --
  2835.  *
  2836.  *    Procedures to evaluate an expression in an object and return its
  2837.  *    value in a particular form.
  2838.  *
  2839.  * Results:
  2840.  *    Each of the procedures below returns a standard Tcl result
  2841.  *    object. If an error occurs then an error message is left in the
  2842.  *    interpreter's result. Otherwise the value of the expression, in the
  2843.  *    appropriate form, is stored at *ptr. If the expression had a result
  2844.  *    that was incompatible with the desired form then an error is
  2845.  *    returned.
  2846.  *
  2847.  * Side effects:
  2848.  *    None.
  2849.  *
  2850.  *--------------------------------------------------------------
  2851.  */
  2852.  
  2853. int
  2854. Tcl_ExprLongObj(interp, objPtr, ptr)
  2855.     Tcl_Interp *interp;            /* Context in which to evaluate the
  2856.                      * expression. */
  2857.     register Tcl_Obj *objPtr;        /* Expression to evaluate. */
  2858.     long *ptr;                /* Where to store long result. */
  2859. {
  2860.     Tcl_Obj *resultPtr;
  2861.     int result;
  2862.  
  2863.     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  2864.     if (result == TCL_OK) {
  2865.     if (resultPtr->typePtr == &tclIntType) {
  2866.         *ptr = resultPtr->internalRep.longValue;
  2867.     } else if (resultPtr->typePtr == &tclDoubleType) {
  2868.         *ptr = (long) resultPtr->internalRep.doubleValue;
  2869.     } else {
  2870.         result = Tcl_GetLongFromObj(interp, resultPtr, ptr);
  2871.         if (result != TCL_OK) {
  2872.         return result;
  2873.         }
  2874.     }
  2875.     Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2876.     }
  2877.     return result;
  2878. }
  2879.  
  2880. int
  2881. Tcl_ExprDoubleObj(interp, objPtr, ptr)
  2882.     Tcl_Interp *interp;            /* Context in which to evaluate the
  2883.                      * expression. */
  2884.     register Tcl_Obj *objPtr;        /* Expression to evaluate. */
  2885.     double *ptr;            /* Where to store double result. */
  2886. {
  2887.     Tcl_Obj *resultPtr;
  2888.     int result;
  2889.  
  2890.     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  2891.     if (result == TCL_OK) {
  2892.     if (resultPtr->typePtr == &tclIntType) {
  2893.         *ptr = (double) resultPtr->internalRep.longValue;
  2894.     } else if (resultPtr->typePtr == &tclDoubleType) {
  2895.         *ptr = resultPtr->internalRep.doubleValue;
  2896.     } else {
  2897.         result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
  2898.         if (result != TCL_OK) {
  2899.         return result;
  2900.         }
  2901.     }
  2902.     Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2903.     }
  2904.     return result;
  2905. }
  2906.  
  2907. int
  2908. Tcl_ExprBooleanObj(interp, objPtr, ptr)
  2909.     Tcl_Interp *interp;            /* Context in which to evaluate the
  2910.                      * expression. */
  2911.     register Tcl_Obj *objPtr;        /* Expression to evaluate. */
  2912.     int *ptr;                /* Where to store 0/1 result. */
  2913. {
  2914.     Tcl_Obj *resultPtr;
  2915.     int result;
  2916.  
  2917.     result = Tcl_ExprObj(interp, objPtr, &resultPtr);
  2918.     if (result == TCL_OK) {
  2919.     if (resultPtr->typePtr == &tclIntType) {
  2920.         *ptr = (resultPtr->internalRep.longValue != 0);
  2921.     } else if (resultPtr->typePtr == &tclDoubleType) {
  2922.         *ptr = (resultPtr->internalRep.doubleValue != 0.0);
  2923.     } else {
  2924.         result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
  2925.         if (result != TCL_OK) {
  2926.         return result;
  2927.         }
  2928.     }
  2929.     Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  2930.     }
  2931.     return result;
  2932. }
  2933.  
  2934. /*
  2935.  *----------------------------------------------------------------------
  2936.  *
  2937.  * TclInvoke --
  2938.  *
  2939.  *    Invokes a Tcl command, given an argv/argc, from either the
  2940.  *    exposed or the hidden sets of commands in the given interpreter.
  2941.  *    NOTE: The command is invoked in the current stack frame of
  2942.  *    the interpreter, thus it can modify local variables.
  2943.  *
  2944.  * Results:
  2945.  *    A standard Tcl result.
  2946.  *
  2947.  * Side effects:
  2948.  *    Whatever the command does.
  2949.  *
  2950.  *----------------------------------------------------------------------
  2951.  */
  2952.  
  2953. int
  2954. TclInvoke(interp, argc, argv, flags)
  2955.     Tcl_Interp *interp;        /* Where to invoke the command. */
  2956.     int argc;            /* Count of args. */
  2957.     register char **argv;    /* The arg strings; argv[0] is the name of
  2958.                                  * the command to invoke. */
  2959.     int flags;            /* Combination of flags controlling the
  2960.                  * call: TCL_INVOKE_HIDDEN and
  2961.                  * TCL_INVOKE_NO_UNKNOWN. */
  2962. {
  2963.     register Tcl_Obj *objPtr;
  2964.     register int i;
  2965.     int length, result;
  2966.  
  2967.     /*
  2968.      * This procedure generates an objv array for object arguments that hold
  2969.      * the argv strings. It starts out with stack-allocated space but uses
  2970.      * dynamically-allocated storage if needed.
  2971.      */
  2972.  
  2973. #define NUM_ARGS 20
  2974.     Tcl_Obj *(objStorage[NUM_ARGS]);
  2975.     register Tcl_Obj **objv = objStorage;
  2976.  
  2977.     /*
  2978.      * Create the object argument array "objv". Make sure objv is large
  2979.      * enough to hold the objc arguments plus 1 extra for the zero
  2980.      * end-of-objv word.
  2981.      */
  2982.  
  2983.     if ((argc + 1) > NUM_ARGS) {
  2984.     objv = (Tcl_Obj **)
  2985.         ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
  2986.     }
  2987.  
  2988.     for (i = 0;  i < argc;  i++) {
  2989.     length = strlen(argv[i]);
  2990.     objv[i] = Tcl_NewStringObj(argv[i], length);
  2991.     Tcl_IncrRefCount(objv[i]);
  2992.     }
  2993.     objv[argc] = 0;
  2994.  
  2995.     /*
  2996.      * Use TclObjInterpProc to actually invoke the command.
  2997.      */
  2998.  
  2999.     result = TclObjInvoke(interp, argc, objv, flags);
  3000.  
  3001.     /*
  3002.      * Move the interpreter's object result to the string result, 
  3003.      * then reset the object result.
  3004.      * FAILS IF OBJECT RESULT'S STRING REPRESENTATION CONTAINS NULLS.
  3005.      */
  3006.     
  3007.     Tcl_SetResult(interp,
  3008.         TclGetStringFromObj(Tcl_GetObjResult(interp), (int *) NULL),
  3009.         TCL_VOLATILE);
  3010.  
  3011.     /*
  3012.      * Decrement the ref counts on the objv elements since we are done
  3013.      * with them.
  3014.      */
  3015.  
  3016.     for (i = 0;  i < argc;  i++) {
  3017.     objPtr = objv[i];
  3018.     Tcl_DecrRefCount(objPtr);
  3019.     }
  3020.     
  3021.     /*
  3022.      * Free the objv array if malloc'ed storage was used.
  3023.      */
  3024.  
  3025.     if (objv != objStorage) {
  3026.     ckfree((char *) objv);
  3027.     }
  3028.     return result;
  3029. #undef NUM_ARGS
  3030. }
  3031.  
  3032. /*
  3033.  *----------------------------------------------------------------------
  3034.  *
  3035.  * TclGlobalInvoke --
  3036.  *
  3037.  *    Invokes a Tcl command, given an argv/argc, from either the
  3038.  *    exposed or hidden sets of commands in the given interpreter.
  3039.  *    NOTE: The command is invoked in the global stack frame of
  3040.  *    the interpreter, thus it cannot see any current state on
  3041.  *    the stack for that interpreter.
  3042.  *
  3043.  * Results:
  3044.  *    A standard Tcl result.
  3045.  *
  3046.  * Side effects:
  3047.  *    Whatever the command does.
  3048.  *
  3049.  *----------------------------------------------------------------------
  3050.  */
  3051.  
  3052. int
  3053. TclGlobalInvoke(interp, argc, argv, flags)
  3054.     Tcl_Interp *interp;        /* Where to invoke the command. */
  3055.     int argc;            /* Count of args. */
  3056.     register char **argv;    /* The arg strings; argv[0] is the name of
  3057.                                  * the command to invoke. */
  3058.     int flags;            /* Combination of flags controlling the
  3059.                  * call: TCL_INVOKE_HIDDEN and
  3060.                  * TCL_INVOKE_NO_UNKNOWN. */
  3061. {
  3062.     register Interp *iPtr = (Interp *) interp;
  3063.     int result;
  3064.     CallFrame *savedVarFramePtr;
  3065.  
  3066.     savedVarFramePtr = iPtr->varFramePtr;
  3067.     iPtr->varFramePtr = NULL;
  3068.     result = TclInvoke(interp, argc, argv, flags);
  3069.     iPtr->varFramePtr = savedVarFramePtr;
  3070.     return result;
  3071. }
  3072.  
  3073. /*
  3074.  *----------------------------------------------------------------------
  3075.  *
  3076.  * TclObjInvokeGlobal --
  3077.  *
  3078.  *    Object version: Invokes a Tcl command, given an objv/objc, from
  3079.  *    either the exposed or hidden set of commands in the given
  3080.  *    interpreter.
  3081.  *    NOTE: The command is invoked in the global stack frame of the
  3082.  *    interpreter, thus it cannot see any current state on the
  3083.  *    stack of that interpreter.
  3084.  *
  3085.  * Results:
  3086.  *    A standard Tcl result.
  3087.  *
  3088.  * Side effects:
  3089.  *    Whatever the command does.
  3090.  *
  3091.  *----------------------------------------------------------------------
  3092.  */
  3093.  
  3094. int
  3095. TclObjInvokeGlobal(interp, objc, objv, flags)
  3096.     Tcl_Interp *interp;        /* Interpreter in which command is
  3097.                  * to be invoked. */
  3098.     int objc;            /* Count of arguments. */
  3099.     Tcl_Obj *CONST objv[];    /* Argument value objects; objv[0]
  3100.                  * points to the name of the
  3101.                  * command to invoke. */
  3102.     int flags;            /* Combination of flags controlling
  3103.                                  * the call: TCL_INVOKE_HIDDEN and
  3104.                                  * TCL_INVOKE_NO_UNKNOWN. */
  3105. {
  3106.     register Interp *iPtr = (Interp *) interp;
  3107.     int result;
  3108.     CallFrame *savedVarFramePtr;
  3109.  
  3110.     savedVarFramePtr = iPtr->varFramePtr;
  3111.     iPtr->varFramePtr = NULL;
  3112.     result = TclObjInvoke(interp, objc, objv, flags);
  3113.     iPtr->varFramePtr = savedVarFramePtr;
  3114.     return result;
  3115. }
  3116.  
  3117. /*
  3118.  *----------------------------------------------------------------------
  3119.  *
  3120.  * TclObjInvoke --
  3121.  *
  3122.  *    Invokes a Tcl command, given an objv/objc, from either the
  3123.  *    exposed or the hidden sets of commands in the given interpreter.
  3124.  *
  3125.  * Results:
  3126.  *    A standard Tcl object result.
  3127.  *
  3128.  * Side effects:
  3129.  *    Whatever the command does.
  3130.  *
  3131.  *----------------------------------------------------------------------
  3132.  */
  3133.  
  3134. int
  3135. TclObjInvoke(interp, objc, objv, flags)
  3136.     Tcl_Interp *interp;        /* Interpreter in which command is
  3137.                  * to be invoked. */
  3138.     int objc;            /* Count of arguments. */
  3139.     Tcl_Obj *CONST objv[];    /* Argument value objects; objv[0]
  3140.                  * points to the name of the
  3141.                  * command to invoke. */
  3142.     int flags;            /* Combination of flags controlling
  3143.                                  * the call: TCL_INVOKE_HIDDEN and
  3144.                                  * TCL_INVOKE_NO_UNKNOWN. */
  3145. {
  3146.     register Interp *iPtr = (Interp *) interp;
  3147.     Tcl_HashTable *hTblPtr;    /* Table of hidden commands. */
  3148.     char *cmdName;        /* Name of the command from objv[0]. */
  3149.     register Tcl_HashEntry *hPtr;
  3150.     Tcl_Command cmd;
  3151.     Command *cmdPtr;
  3152.     int localObjc;        /* Used to invoke "unknown" if the */
  3153.     Tcl_Obj **localObjv = NULL;    /* command is not found. */
  3154.     register int i;
  3155.     int length, result;
  3156.     char *bytes;
  3157.  
  3158.     if (interp == (Tcl_Interp *) NULL) {
  3159.         return TCL_ERROR;
  3160.     }
  3161.  
  3162.     if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
  3163.         Tcl_AppendToObj(Tcl_GetObjResult(interp),
  3164.             "illegal argument vector", -1);
  3165.         return TCL_ERROR;
  3166.     }
  3167.  
  3168.     /*
  3169.      * THE FOLLOWING CODE FAILS IF THE STRING REP CONTAINS NULLS.
  3170.      */
  3171.     
  3172.     cmdName = Tcl_GetStringFromObj(objv[0], (int *) NULL);
  3173.     if (flags & TCL_INVOKE_HIDDEN) {
  3174.         /*
  3175.          * Find the table of hidden commands; error out if none.
  3176.          */
  3177.  
  3178.         hTblPtr = (Tcl_HashTable *)
  3179.             Tcl_GetAssocData(interp, "tclHiddenCmds", NULL);
  3180.         if (hTblPtr == (Tcl_HashTable *) NULL) {
  3181.             badhiddenCmdToken:
  3182.         Tcl_ResetResult(interp);
  3183.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  3184.              "invalid hidden command name \"", cmdName, "\"",
  3185.              (char *) NULL);
  3186.             return TCL_ERROR;
  3187.         }
  3188.         hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
  3189.  
  3190.         /*
  3191.          * We never invoke "unknown" for hidden commands.
  3192.          */
  3193.         
  3194.         if (hPtr == NULL) {
  3195.             goto badhiddenCmdToken;
  3196.         }
  3197.     cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  3198.     } else {
  3199.     cmdPtr = NULL;
  3200.     cmd = Tcl_FindCommand(interp, cmdName,
  3201.             (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
  3202.         if (cmd != (Tcl_Command) NULL) {
  3203.         cmdPtr = (Command *) cmd;
  3204.         }
  3205.     if (cmdPtr == NULL) {
  3206.             if (!(flags & TCL_INVOKE_NO_UNKNOWN)) {
  3207.         cmd = Tcl_FindCommand(interp, "unknown",
  3208.                         (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
  3209.         if (cmd != (Tcl_Command) NULL) {
  3210.                 cmdPtr = (Command *) cmd;
  3211.                 }
  3212.                 if (cmdPtr != NULL) {
  3213.                     localObjc = (objc + 1);
  3214.                     localObjv = (Tcl_Obj **)
  3215.             ckalloc((unsigned) (sizeof(Tcl_Obj *) * localObjc));
  3216.             localObjv[0] = Tcl_NewStringObj("unknown", -1);
  3217.             Tcl_IncrRefCount(localObjv[0]);
  3218.                     for (i = 0;  i < objc;  i++) {
  3219.                         localObjv[i+1] = objv[i];
  3220.                     }
  3221.                     objc = localObjc;
  3222.                     objv = localObjv;
  3223.                 }
  3224.             }
  3225.  
  3226.             /*
  3227.              * Check again if we found the command. If not, "unknown" is
  3228.              * not present and we cannot help, or the caller said not to
  3229.              * call "unknown" (they specified TCL_INVOKE_NO_UNKNOWN).
  3230.              */
  3231.  
  3232.             if (cmdPtr == NULL) {
  3233.         Tcl_ResetResult(interp);
  3234.         Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
  3235.             "invalid command name \"",  cmdName, "\"", 
  3236.              (char *) NULL);
  3237.                 return TCL_ERROR;
  3238.             }
  3239.         }
  3240.     }
  3241.  
  3242.     /*
  3243.      * Invoke the command procedure. First reset the interpreter's string
  3244.      * and object results to their default empty values since they could
  3245.      * have gotten changed by earlier invocations.
  3246.      */
  3247.  
  3248.     Tcl_ResetResult(interp);
  3249.     iPtr->cmdCount++;
  3250.     result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
  3251.  
  3252.     /*
  3253.      * If an error occurred, record information about what was being
  3254.      * executed when the error occurred.
  3255.      */
  3256.  
  3257.     if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
  3258.         Tcl_DString ds;
  3259.         
  3260.         Tcl_DStringInit(&ds);
  3261.         if (!(iPtr->flags & ERR_IN_PROGRESS)) {
  3262.             Tcl_DStringAppend(&ds, "\n    while invoking\n\"", -1);
  3263.         } else {
  3264.             Tcl_DStringAppend(&ds, "\n    invoked from within\n\"", -1);
  3265.         }
  3266.         for (i = 0;  i < objc;  i++) {
  3267.         bytes = Tcl_GetStringFromObj(objv[i], &length);
  3268.             Tcl_DStringAppend(&ds, bytes, length);
  3269.             if (i < (objc - 1)) {
  3270.                 Tcl_DStringAppend(&ds, " ", -1);
  3271.             } else if (Tcl_DStringLength(&ds) > 100) {
  3272.                 Tcl_DStringSetLength(&ds, 100);
  3273.                 Tcl_DStringAppend(&ds, "...", -1);
  3274.                 break;
  3275.             }
  3276.         }
  3277.         
  3278.         Tcl_DStringAppend(&ds, "\"", -1);
  3279.         Tcl_AddObjErrorInfo(interp, Tcl_DStringValue(&ds), -1);
  3280.         Tcl_DStringFree(&ds);
  3281.     iPtr->flags &= ~ERR_ALREADY_LOGGED;
  3282.     }
  3283.  
  3284.     /*
  3285.      * Free any locally allocated storage used to call "unknown".
  3286.      */
  3287.  
  3288.     if (localObjv != (Tcl_Obj **) NULL) {
  3289.         ckfree((char *) localObjv);
  3290.     }
  3291.     return result;
  3292. }
  3293.  
  3294. /*
  3295.  *--------------------------------------------------------------
  3296.  *
  3297.  * Tcl_ExprString --
  3298.  *
  3299.  *    Evaluate an expression in a string and return its value in string
  3300.  *    form.
  3301.  *
  3302.  * Results:
  3303.  *    A standard Tcl result. If the result is TCL_OK, then the
  3304.  *    interpreter's result is set to the string value of the
  3305.  *    expression. If the result is TCL_OK, then interp->result
  3306.  *    contains an error message.
  3307.  *
  3308.  * Side effects:
  3309.  *    A Tcl object is allocated to hold a copy of the expression string.
  3310.  *    This expression object is passed to Tcl_ExprObj and then
  3311.  *    deallocated.
  3312.  *
  3313.  *--------------------------------------------------------------
  3314.  */
  3315.  
  3316. int
  3317. Tcl_ExprString(interp, string)
  3318.     Tcl_Interp *interp;        /* Context in which to evaluate the
  3319.                  * expression. */
  3320.     char *string;        /* Expression to evaluate. */
  3321. {
  3322.     register Tcl_Obj *exprPtr;
  3323.     Tcl_Obj *resultPtr;
  3324.     int length = strlen(string);
  3325.     char buf[100];
  3326.     int result = TCL_OK;
  3327.  
  3328.     if (length > 0) {
  3329.     TclNewObj(exprPtr);
  3330.     TclInitStringRep(exprPtr, string, length);
  3331.     Tcl_IncrRefCount(exprPtr);
  3332.  
  3333.     result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
  3334.     if (result == TCL_OK) {
  3335.         /*
  3336.          * Set the interpreter's string result from the result object.
  3337.          */
  3338.         
  3339.         if (resultPtr->typePtr == &tclIntType) {
  3340.         sprintf(buf, "%ld", resultPtr->internalRep.longValue);
  3341.         Tcl_SetResult(interp, buf, TCL_VOLATILE);
  3342.         } else if (resultPtr->typePtr == &tclDoubleType) {
  3343.         Tcl_PrintDouble((Tcl_Interp *) NULL,
  3344.                 resultPtr->internalRep.doubleValue, buf);
  3345.         Tcl_SetResult(interp, buf, TCL_VOLATILE);
  3346.         } else {
  3347.         /*
  3348.          * Set interpreter's string result from the result object.
  3349.          * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
  3350.          */
  3351.         
  3352.         Tcl_SetResult(interp,
  3353.                     TclGetStringFromObj(resultPtr, (int *) NULL),
  3354.                     TCL_VOLATILE);
  3355.         }
  3356.         Tcl_DecrRefCount(resultPtr);  /* discard the result object */
  3357.     } else {
  3358.         /*
  3359.          * Move the interpreter's object result to the string result, 
  3360.          * then reset the object result.
  3361.          * FAILS IF OBJECT RESULT'S STRING REPRESENTATION HAS NULLS.
  3362.          */
  3363.         
  3364.         Tcl_SetResult(interp,
  3365.                 TclGetStringFromObj(Tcl_GetObjResult(interp),
  3366.                 (int *) NULL),
  3367.                 TCL_VOLATILE);
  3368.     }
  3369.     Tcl_DecrRefCount(exprPtr); /* discard the expression object */
  3370.     } else {
  3371.     /*
  3372.      * An empty string. Just set the interpreter's result to 0.
  3373.      */
  3374.     
  3375.     Tcl_SetResult(interp, "0", TCL_VOLATILE);
  3376.     }
  3377.     return result;
  3378. }
  3379.  
  3380. /*
  3381.  *--------------------------------------------------------------
  3382.  *
  3383.  * Tcl_ExprObj --
  3384.  *
  3385.  *    Evaluate an expression in a Tcl_Obj.
  3386.  *
  3387.  * Results:
  3388.  *    A standard Tcl object result. If the result is other than TCL_OK,
  3389.  *    then the interpreter's result contains an error message. If the
  3390.  *    result is TCL_OK, then a pointer to the expression's result value
  3391.  *    object is stored in resultPtrPtr. In that case, the object's ref
  3392.  *    count is incremented to reflect the reference returned to the
  3393.  *    caller; the caller is then responsible for the resulting object
  3394.  *    and must, for example, decrement the ref count when it is finished
  3395.  *    with the object.
  3396.  *
  3397.  * Side effects:
  3398.  *    Any side effects caused by subcommands in the expression, if any.
  3399.  *    The interpreter result is not modified unless there is an error.
  3400.  *
  3401.  *--------------------------------------------------------------
  3402.  */
  3403.  
  3404. int
  3405. Tcl_ExprObj(interp, objPtr, resultPtrPtr)
  3406.     Tcl_Interp *interp;        /* Context in which to evaluate the
  3407.                  * expression. */
  3408.     register Tcl_Obj *objPtr;    /* Points to Tcl object containing
  3409.                  * expression to evaluate. */
  3410.     Tcl_Obj **resultPtrPtr;    /* Where the Tcl_Obj* that is the expression
  3411.                  * result is stored if no errors occur. */
  3412. {
  3413.     Interp *iPtr = (Interp *) interp;
  3414.     CompileEnv compEnv;        /* Compilation environment structure
  3415.                  * allocated in frame. */
  3416.     register ByteCode *codePtr = NULL;
  3417.                     /* Tcl Internal type of bytecode.
  3418.                  * Initialized to avoid compiler warning. */
  3419.     AuxData *auxDataPtr;
  3420.     Interp dummy;
  3421.     Tcl_Obj *saveObjPtr;
  3422.     char *string;
  3423.     int result;
  3424.     int i;
  3425.  
  3426.     /*
  3427.      * Get the ByteCode from the object. If it exists, make sure it hasn't
  3428.      * been invalidated by, e.g., someone redefining a command with a
  3429.      * compile procedure (this might make the compiled code wrong). If
  3430.      * necessary, convert the object to be a ByteCode object and compile it.
  3431.      * Also, if the code was compiled in/for a different interpreter, we
  3432.      * recompile it.
  3433.      * THIS FAILS IF THE OBJECT'S STRING REP HAS A NULL BYTE.
  3434.      */
  3435.  
  3436.     if (objPtr->typePtr == &tclByteCodeType) {
  3437.     codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
  3438.     if ((codePtr->iPtr != iPtr)
  3439.             || (codePtr->compileEpoch != iPtr->compileEpoch)) {
  3440.         tclByteCodeType.freeIntRepProc(objPtr);
  3441.         objPtr->typePtr = (Tcl_ObjType *) NULL;
  3442.     }
  3443.     }
  3444.     if (objPtr->typePtr != &tclByteCodeType) {
  3445.     int length;
  3446.     string = Tcl_GetStringFromObj(objPtr, &length);
  3447.     TclInitCompileEnv(interp, &compEnv, string);
  3448.     result = TclCompileExpr(interp, string, string + length,
  3449.         /*flags*/ 0, &compEnv);
  3450.     if (result == TCL_OK) {
  3451.         /*
  3452.          * If the expression yielded no instructions (e.g., was empty),
  3453.          * push an integer zero object as the expressions's result.
  3454.          */
  3455.         
  3456.         if (compEnv.codeNext == NULL) {
  3457.         int objIndex = TclObjIndexForString("0", 0,
  3458.             /*allocStrRep*/ 0, /*inHeap*/ 0, &compEnv);
  3459.         Tcl_Obj *objPtr = compEnv.objArrayPtr[objIndex];
  3460.  
  3461.         Tcl_InvalidateStringRep(objPtr);
  3462.         objPtr->internalRep.longValue = 0;
  3463.         objPtr->typePtr = &tclIntType;
  3464.         
  3465.         TclEmitPush(objIndex, &compEnv);
  3466.         }
  3467.         
  3468.         /*
  3469.          * Add done instruction at the end of the instruction sequence.
  3470.          */
  3471.         
  3472.         TclEmitOpcode(INST_DONE, &compEnv);
  3473.         
  3474.         TclInitByteCodeObj(objPtr, &compEnv);
  3475.         codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr;
  3476.         if (tclTraceCompile == 2) {
  3477.         TclPrintByteCodeObj(interp, objPtr);
  3478.         }
  3479.         TclFreeCompileEnv(&compEnv);
  3480.     } else {
  3481.         /*
  3482.          * Compilation errors. Decrement the ref counts on any objects
  3483.          * in the object array before freeing the compilation
  3484.          * environment.
  3485.          */
  3486.         
  3487.         for (i = 0;  i < compEnv.objArrayNext;  i++) {
  3488.         Tcl_Obj *elemPtr = compEnv.objArrayPtr[i];
  3489.         Tcl_DecrRefCount(elemPtr);
  3490.         }
  3491.  
  3492.         auxDataPtr = compEnv.auxDataArrayPtr;
  3493.         for (i = 0;  i < compEnv.auxDataArrayNext;  i++) {
  3494.         if (auxDataPtr->freeProc != NULL) {
  3495.             auxDataPtr->freeProc(auxDataPtr->clientData);
  3496.         }
  3497.         auxDataPtr++;
  3498.         }
  3499.         TclFreeCompileEnv(&compEnv);
  3500.         return result;
  3501.     }
  3502.     }
  3503.  
  3504.     /*
  3505.      * Execute the expression after first saving the interpreter's result.
  3506.      */
  3507.     
  3508.     dummy.objResultPtr = Tcl_NewObj();
  3509.     Tcl_IncrRefCount(dummy.objResultPtr);
  3510.     if (interp->freeProc == 0) {
  3511.     dummy.freeProc = (Tcl_FreeProc *) 0;
  3512.     dummy.result = "";
  3513.     Tcl_SetResult((Tcl_Interp *) &dummy, interp->result,
  3514.             TCL_VOLATILE);
  3515.     } else {
  3516.     dummy.freeProc = interp->freeProc;
  3517.     dummy.result = interp->result;
  3518.     interp->freeProc = (Tcl_FreeProc *) 0;
  3519.     }
  3520.     
  3521.     saveObjPtr = Tcl_GetObjResult(interp);
  3522.     Tcl_IncrRefCount(saveObjPtr);
  3523.     
  3524.     /*
  3525.      * Increment the code's ref count while it is being executed. If
  3526.      * afterwards no references to it remain, free the code.
  3527.      */
  3528.     
  3529.     codePtr->refCount++;
  3530.     result = TclExecuteByteCode(interp, codePtr);
  3531.     codePtr->refCount--;
  3532.     if (codePtr->refCount <= 0) {
  3533.     TclCleanupByteCode(codePtr);
  3534.     }
  3535.     
  3536.     /*
  3537.      * If the expression evaluated successfully, store a pointer to its
  3538.      * value object in resultPtrPtr then restore the old interpreter result.
  3539.      * We increment the object's ref count to reflect the reference that we
  3540.      * are returning to the caller. We also decrement the ref count of the
  3541.      * interpreter's result object after calling Tcl_SetResult since we
  3542.      * next store into that field directly.
  3543.      */
  3544.     
  3545.     if (result == TCL_OK) {
  3546.     *resultPtrPtr = iPtr->objResultPtr;
  3547.     Tcl_IncrRefCount(iPtr->objResultPtr);
  3548.     
  3549.     Tcl_SetResult(interp, dummy.result,
  3550.             ((dummy.freeProc == 0) ? TCL_VOLATILE : dummy.freeProc));
  3551.     Tcl_DecrRefCount(iPtr->objResultPtr);
  3552.     iPtr->objResultPtr = saveObjPtr;
  3553.     } else {
  3554.     Tcl_DecrRefCount(saveObjPtr);
  3555.     Tcl_FreeResult((Tcl_Interp *) &dummy);
  3556.     }
  3557.  
  3558.     Tcl_DecrRefCount(dummy.objResultPtr);
  3559.     dummy.objResultPtr = NULL;
  3560.     return result;
  3561. }
  3562.  
  3563. /*
  3564.  *----------------------------------------------------------------------
  3565.  *
  3566.  * Tcl_CreateTrace --
  3567.  *
  3568.  *    Arrange for a procedure to be called to trace command execution.
  3569.  *
  3570.  * Results:
  3571.  *    The return value is a token for the trace, which may be passed
  3572.  *    to Tcl_DeleteTrace to eliminate the trace.
  3573.  *
  3574.  * Side effects:
  3575.  *    From now on, proc will be called just before a command procedure
  3576.  *    is called to execute a Tcl command.  Calls to proc will have the
  3577.  *    following form:
  3578.  *
  3579.  *    void
  3580.  *    proc(clientData, interp, level, command, cmdProc, cmdClientData,
  3581.  *        argc, argv)
  3582.  *        ClientData clientData;
  3583.  *        Tcl_Interp *interp;
  3584.  *        int level;
  3585.  *        char *command;
  3586.  *        int (*cmdProc)();
  3587.  *        ClientData cmdClientData;
  3588.  *        int argc;
  3589.  *        char **argv;
  3590.  *    {
  3591.  *    }
  3592.  *
  3593.  *    The clientData and interp arguments to proc will be the same
  3594.  *    as the corresponding arguments to this procedure.  Level gives
  3595.  *    the nesting level of command interpretation for this interpreter
  3596.  *    (0 corresponds to top level).  Command gives the ASCII text of
  3597.  *    the raw command, cmdProc and cmdClientData give the procedure that
  3598.  *    will be called to process the command and the ClientData value it
  3599.  *    will receive, and argc and argv give the arguments to the
  3600.  *    command, after any argument parsing and substitution.  Proc
  3601.  *    does not return a value.
  3602.  *
  3603.  *----------------------------------------------------------------------
  3604.  */
  3605.  
  3606. Tcl_Trace
  3607. Tcl_CreateTrace(interp, level, proc, clientData)
  3608.     Tcl_Interp *interp;        /* Interpreter in which to create trace. */
  3609.     int level;            /* Only call proc for commands at nesting
  3610.                  * level<=argument level (1=>top level). */
  3611.     Tcl_CmdTraceProc *proc;    /* Procedure to call before executing each
  3612.                  * command. */
  3613.     ClientData clientData;    /* Arbitrary value word to pass to proc. */
  3614. {
  3615.     register Trace *tracePtr;
  3616.     register Interp *iPtr = (Interp *) interp;
  3617.  
  3618.     /*
  3619.      * Invalidate existing compiled code for this interpreter and arrange
  3620.      * (by setting the DONT_COMPILE_CMDS_INLINE flag) that when compiling
  3621.      * new code, no commands will be compiled inline (i.e., into an inline
  3622.      * sequence of instructions). We do this because commands that were
  3623.      * compiled inline will never result in a command trace being called.
  3624.      */
  3625.  
  3626.     iPtr->compileEpoch++;
  3627.     iPtr->flags |= DONT_COMPILE_CMDS_INLINE;
  3628.  
  3629.     tracePtr = (Trace *) ckalloc(sizeof(Trace));
  3630.     tracePtr->level = level;
  3631.     tracePtr->proc = proc;
  3632.     tracePtr->clientData = clientData;
  3633.     tracePtr->nextPtr = iPtr->tracePtr;
  3634.     iPtr->tracePtr = tracePtr;
  3635.  
  3636.     return (Tcl_Trace) tracePtr;
  3637. }
  3638.  
  3639. /*
  3640.  *----------------------------------------------------------------------
  3641.  *
  3642.  * Tcl_DeleteTrace --
  3643.  *
  3644.  *    Remove a trace.
  3645.  *
  3646.  * Results:
  3647.  *    None.
  3648.  *
  3649.  * Side effects:
  3650.  *    From now on there will be no more calls to the procedure given
  3651.  *    in trace.
  3652.  *
  3653.  *----------------------------------------------------------------------
  3654.  */
  3655.  
  3656. void
  3657. Tcl_DeleteTrace(interp, trace)
  3658.     Tcl_Interp *interp;        /* Interpreter that contains trace. */
  3659.     Tcl_Trace trace;        /* Token for trace (returned previously by
  3660.                  * Tcl_CreateTrace). */
  3661. {
  3662.     register Interp *iPtr = (Interp *) interp;
  3663.     register Trace *tracePtr = (Trace *) trace;
  3664.     register Trace *tracePtr2;
  3665.  
  3666.     if (iPtr->tracePtr == tracePtr) {
  3667.     iPtr->tracePtr = tracePtr->nextPtr;
  3668.     ckfree((char *) tracePtr);
  3669.     } else {
  3670.     for (tracePtr2 = iPtr->tracePtr; tracePtr2 != NULL;
  3671.         tracePtr2 = tracePtr2->nextPtr) {
  3672.         if (tracePtr2->nextPtr == tracePtr) {
  3673.         tracePtr2->nextPtr = tracePtr->nextPtr;
  3674.         ckfree((char *) tracePtr);
  3675.         break;
  3676.         }
  3677.     }
  3678.     }
  3679.  
  3680.     if (iPtr->tracePtr == NULL) {
  3681.     /*
  3682.      * When compiling new code, allow commands to be compiled inline.
  3683.      */
  3684.  
  3685.     iPtr->flags &= ~DONT_COMPILE_CMDS_INLINE;
  3686.     }
  3687. }
  3688.  
  3689. /*
  3690.  *----------------------------------------------------------------------
  3691.  *
  3692.  * Tcl_AddErrorInfo --
  3693.  *
  3694.  *    Add information to the "errorInfo" variable that describes the
  3695.  *    current error.
  3696.  *
  3697.  * Results:
  3698.  *    None.
  3699.  *
  3700.  * Side effects:
  3701.  *    The contents of message are added to the "errorInfo" variable.
  3702.  *    If Tcl_Eval has been called since the current value of errorInfo
  3703.  *    was set, errorInfo is cleared before adding the new message.
  3704.  *    If we are just starting to log an error, errorInfo is initialized
  3705.  *    from the error message in the interpreter's result.
  3706.  *
  3707.  *----------------------------------------------------------------------
  3708.  */
  3709.  
  3710. void
  3711. Tcl_AddErrorInfo(interp, message)
  3712.     Tcl_Interp *interp;        /* Interpreter to which error information
  3713.                  * pertains. */
  3714.     char *message;        /* Message to record. */
  3715. {
  3716.     Tcl_AddObjErrorInfo(interp, message, -1);
  3717. }
  3718.  
  3719. /*
  3720.  *----------------------------------------------------------------------
  3721.  *
  3722.  * Tcl_AddObjErrorInfo --
  3723.  *
  3724.  *    Add information to the "errorInfo" variable that describes the
  3725.  *    current error. This routine differs from Tcl_AddErrorInfo by
  3726.  *    taking a byte pointer and length.
  3727.  *
  3728.  * Results:
  3729.  *    None.
  3730.  *
  3731.  * Side effects:
  3732.  *    "length" bytes from "message" are added to the "errorInfo" variable.
  3733.  *    If "length" is negative, use bytes up to the first NULL byte.
  3734.  *    If Tcl_EvalObj has been called since the current value of errorInfo
  3735.  *    was set, errorInfo is cleared before adding the new message.
  3736.  *    If we are just starting to log an error, errorInfo is initialized
  3737.  *    from the error message in the interpreter's result.
  3738.  *
  3739.  *----------------------------------------------------------------------
  3740.  */
  3741.  
  3742. void
  3743. Tcl_AddObjErrorInfo(interp, message, length)
  3744.     Tcl_Interp *interp;        /* Interpreter to which error information
  3745.                  * pertains. */
  3746.     char *message;        /* Points to the first byte of an array of
  3747.                  * bytes of the message. */
  3748.     register int length;    /* The number of bytes in the message.
  3749.                  * If < 0, then append all bytes up to a
  3750.                  * NULL byte. */
  3751. {
  3752.     register Interp *iPtr = (Interp *) interp;
  3753.     Tcl_Obj *namePtr, *messagePtr;
  3754.     
  3755.     /*
  3756.      * If we are just starting to log an error, errorInfo is initialized
  3757.      * from the error message in the interpreter's result.
  3758.      */
  3759.  
  3760.     namePtr = Tcl_NewStringObj("errorInfo", -1);
  3761.     Tcl_IncrRefCount(namePtr);
  3762.     
  3763.     if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
  3764.     iPtr->flags |= ERR_IN_PROGRESS;
  3765.  
  3766.     if (iPtr->result[0] == 0) {
  3767.         (void) Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL,
  3768.                 iPtr->objResultPtr, TCL_GLOBAL_ONLY);
  3769.     } else {        /* use the string result */
  3770.         Tcl_SetVar2(interp, "errorInfo", (char *) NULL, interp->result,
  3771.             TCL_GLOBAL_ONLY);
  3772.     }
  3773.  
  3774.     /*
  3775.      * If the errorCode variable wasn't set by the code that generated
  3776.      * the error, set it to "NONE".
  3777.      */
  3778.  
  3779.     if (!(iPtr->flags & ERROR_CODE_SET)) {
  3780.         (void) Tcl_SetVar2(interp, "errorCode", (char *) NULL, "NONE",
  3781.             TCL_GLOBAL_ONLY);
  3782.     }
  3783.     }
  3784.  
  3785.     /*
  3786.      * Now append "message" to the end of errorInfo.
  3787.      */
  3788.  
  3789.     if (length != 0) {
  3790.     messagePtr = Tcl_NewStringObj(message, length);
  3791.     Tcl_IncrRefCount(messagePtr);
  3792.     Tcl_ObjSetVar2(interp, namePtr, (Tcl_Obj *) NULL, messagePtr,
  3793.         (TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
  3794.     Tcl_DecrRefCount(messagePtr); /* free msg object appended above */
  3795.     }
  3796.  
  3797.     Tcl_DecrRefCount(namePtr);    /* free the name object */
  3798. }
  3799.  
  3800. /*
  3801.  *----------------------------------------------------------------------
  3802.  *
  3803.  * Tcl_VarEval --
  3804.  *
  3805.  *    Given a variable number of string arguments, concatenate them
  3806.  *    all together and execute the result as a Tcl command.
  3807.  *
  3808.  * Results:
  3809.  *    A standard Tcl return result.  An error message or other
  3810.  *    result may be left in interp->result.
  3811.  *
  3812.  * Side effects:
  3813.  *    Depends on what was done by the command.
  3814.  *
  3815.  *----------------------------------------------------------------------
  3816.  */
  3817.     /* VARARGS2 */ /* ARGSUSED */
  3818. int
  3819. Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
  3820. {
  3821.     va_list argList;
  3822.     Tcl_DString buf;
  3823.     char *string;
  3824.     Tcl_Interp *interp;
  3825.     int result;
  3826.  
  3827.     /*
  3828.      * Copy the strings one after the other into a single larger
  3829.      * string.  Use stack-allocated space for small commands, but if
  3830.      * the command gets too large than call ckalloc to create the
  3831.      * space.
  3832.      */
  3833.  
  3834.     interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
  3835.     Tcl_DStringInit(&buf);
  3836.     while (1) {
  3837.     string = va_arg(argList, char *);
  3838.     if (string == NULL) {
  3839.         break;
  3840.     }
  3841.     Tcl_DStringAppend(&buf, string, -1);
  3842.     }
  3843.     va_end(argList);
  3844.  
  3845.     result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
  3846.     Tcl_DStringFree(&buf);
  3847.     return result;
  3848. }
  3849.  
  3850. /*
  3851.  *----------------------------------------------------------------------
  3852.  *
  3853.  * Tcl_GlobalEval --
  3854.  *
  3855.  *    Evaluate a command at global level in an interpreter.
  3856.  *
  3857.  * Results:
  3858.  *    A standard Tcl result is returned, and interp->result is
  3859.  *    modified accordingly.
  3860.  *
  3861.  * Side effects:
  3862.  *    The command string is executed in interp, and the execution
  3863.  *    is carried out in the variable context of global level (no
  3864.  *    procedures active), just as if an "uplevel #0" command were
  3865.  *    being executed.
  3866.  *
  3867.  *----------------------------------------------------------------------
  3868.  */
  3869.  
  3870. int
  3871. Tcl_GlobalEval(interp, command)
  3872.     Tcl_Interp *interp;        /* Interpreter in which to evaluate command. */
  3873.     char *command;        /* Command to evaluate. */
  3874. {
  3875.     register Interp *iPtr = (Interp *) interp;
  3876.     int result;
  3877.     CallFrame *savedVarFramePtr;
  3878.  
  3879.     savedVarFramePtr = iPtr->varFramePtr;
  3880.     iPtr->varFramePtr = NULL;
  3881.     result = Tcl_Eval(interp, command);
  3882.     iPtr->varFramePtr = savedVarFramePtr;
  3883.     return result;
  3884. }
  3885.  
  3886. /*
  3887.  *----------------------------------------------------------------------
  3888.  *
  3889.  * Tcl_GlobalEvalObj --
  3890.  *
  3891.  *    Execute Tcl commands stored in a Tcl object at global level in
  3892.  *    an interpreter. These commands are compiled into bytecodes if
  3893.  *    necessary.
  3894.  *
  3895.  * Results:
  3896.  *    A standard Tcl result is returned, and the interpreter's result
  3897.  *    contains a Tcl object value to supplement the return code.
  3898.  *
  3899.  * Side effects:
  3900.  *    The object is converted, if necessary, to a ByteCode object that
  3901.  *    holds the bytecode instructions for the commands. Executing the
  3902.  *    commands will almost certainly have side effects that depend on
  3903.  *    those commands.
  3904.  *
  3905.  *    The commands are executed in interp, and the execution
  3906.  *    is carried out in the variable context of global level (no
  3907.  *    procedures active), just as if an "uplevel #0" command were
  3908.  *    being executed.
  3909.  *
  3910.  *----------------------------------------------------------------------
  3911.  */
  3912.  
  3913. int
  3914. Tcl_GlobalEvalObj(interp, objPtr)
  3915.     Tcl_Interp *interp;        /* Interpreter in which to evaluate
  3916.                  * commands. */
  3917.     Tcl_Obj *objPtr;        /* Pointer to object containing commands
  3918.                  * to execute. */
  3919. {
  3920.     register Interp *iPtr = (Interp *) interp;
  3921.     int result;
  3922.     CallFrame *savedVarFramePtr;
  3923.  
  3924.     savedVarFramePtr = iPtr->varFramePtr;
  3925.     iPtr->varFramePtr = NULL;
  3926.     result = Tcl_EvalObj(interp, objPtr);
  3927.     iPtr->varFramePtr = savedVarFramePtr;
  3928.     return result;
  3929. }
  3930.  
  3931. /*
  3932.  *----------------------------------------------------------------------
  3933.  *
  3934.  * Tcl_SetRecursionLimit --
  3935.  *
  3936.  *    Set the maximum number of recursive calls that may be active
  3937.  *    for an interpreter at once.
  3938.  *
  3939.  * Results:
  3940.  *    The return value is the old limit on nesting for interp.
  3941.  *
  3942.  * Side effects:
  3943.  *    None.
  3944.  *
  3945.  *----------------------------------------------------------------------
  3946.  */
  3947.  
  3948. int
  3949. Tcl_SetRecursionLimit(interp, depth)
  3950.     Tcl_Interp *interp;            /* Interpreter whose nesting limit
  3951.                      * is to be set. */
  3952.     int depth;                /* New value for maximimum depth. */
  3953. {
  3954.     Interp *iPtr = (Interp *) interp;
  3955.     int old;
  3956.  
  3957.     old = iPtr->maxNestingDepth;
  3958.     if (depth > 0) {
  3959.     iPtr->maxNestingDepth = depth;
  3960.     }
  3961.     return old;
  3962. }
  3963.  
  3964. /*
  3965.  *----------------------------------------------------------------------
  3966.  *
  3967.  * Tcl_AllowExceptions --
  3968.  *
  3969.  *    Sets a flag in an interpreter so that exceptions can occur
  3970.  *    in the next call to Tcl_Eval without them being turned into
  3971.  *    errors.
  3972.  *
  3973.  * Results:
  3974.  *    None.
  3975.  *
  3976.  * Side effects:
  3977.  *    The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's
  3978.  *    evalFlags structure.  See the reference documentation for
  3979.  *    more details.
  3980.  *
  3981.  *----------------------------------------------------------------------
  3982.  */
  3983.  
  3984. void
  3985. Tcl_AllowExceptions(interp)
  3986.     Tcl_Interp *interp;        /* Interpreter in which to set flag. */
  3987. {
  3988.     Interp *iPtr = (Interp *) interp;
  3989.  
  3990.     iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
  3991. }
  3992.  
  3993.